JS为单线程
宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)
例子1
console.log('script start');
setTimeout(function() {
console.log('timeout1');
}, 10);
new Promise(resolve => {
console.log('promise1');
resolve();
setTimeout(() => console.log('timeout2'), 10);
}).then(function() {
console.log('then1')
})
console.log('script end');
先执行第一个log
setTimeout推入宏队列hong1
遇到promise马上执行打印然后将它所有的then推入微队列后把setTimeout推入宏队列hong2
先执行微队列,所以先打印then里面的。然后宏队列再打印
例子2
console.log('1');
setTimeout(function() {
console.log('2');
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
当在只剩两个宏任务的setTimeout时候执行第一个时,Promise压入了then的微任务,让第二个宏任务又排到微任务后等待
async和await
- await后面接一个会return new promise的函数并执行它
- await只能放在async函数里
function 摇色子(){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
setTimeout(()=>{
resolve(sino)
},3000)
})
}
async function test(){
let n =await 摇色子()
console.log(n)
}
test()
- async函数会返回一个promise,并且Promise对象的状态值是resolved(成功的)
- 如果你没有在async函数中写return,那么Promise对象resolve的值就是是undefined
- 如果你写了return,那么return的值就会作为你成功的时候传入的值
await 等到之后,做了一件什么事情?
- 不是promise对象
- 是promise对象
如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。
- 如果asycn里的代码都是同步的,那么这个函数被调用就会同步执行
- 如果在await后面接的这个promsie都是同步的,后面的promise会同步执行
- 如果await里面的promise没有resolve()的成功函数就不会执行await下面的线程了