搞清async await、微任务,宏任务执行顺序
宏任务
1.script(整体代码)
2.setTimeout
3.setInterval
4.I/O
5.UI交互事件
6.postMessage
7.MessageChannel
8.setImmediate(Node.js 环境)
微任务
1. Promise.then
-
MutaionObserver
-
process.nextTick(Node.js 环境)
一道面试题,帮助搞清async await、微任务,宏任务执行顺序问题
注:小圆圈序号是代码输出的顺序。
async function async1() {
console.log('async1 start')//②执行同步代码2,输出
await async2() //同步代码3,阻塞下面代码,放入微任务队列
console.log('async1 end') //⑥微任务1
}
async function async2() {
console.log('async2') //③执行同步代码3,输出
}
console.log('script start')//①同步代码1,输出
setTimeout(() => {//下一个宏任务,放着
console.log('setTimeout')//⑧
}, 0);
async1() //同步代码2
new Promise(resolve => {
console.log('promise1')//④同步代码4,输出
resolve() //改变promise状态,将promise.then放入微任务队列
})
.then(() => {
console.log('promise2')//⑦微任务2,执行完所有微任务,进入下一轮宏任务,也就是定时器
})
console.log('script end') //⑤同步代码5,完成所有同步代码,去执行本轮所有微任务,也就是微任务1和2
解析:
- 将整个script代码看作第一个宏任务,从上往下,script start是第一个同步代码,输出,碰到定时器,他是一个宏任务,得等本次宏任务执行完才能执行;
- 遇到第二个同步代码async1(),输出里面的async1 start,此时碰到await,将下面要输出async1 end的代码放入微任务队列,记作微任务1,执行第三个同步任务async2(),输出async2;
- 往下new promise,是同步任务,输出promise1,resolve()改变promise状态,将promise.then放入微任务队列里,记作微任务2;
- 最后一行,同步代码,输出script end;
- 本轮宏任务执行完所有同步代码,去执行本轮所有微任务,也就是微任务1和2,输出async1 end,promise2;
- 进入下一轮宏任务,也就是定时器,输出setTimeout;