关于微任务执行时机的问题?

今天在看面试问题的时候遇到了这么一道题:

async function a1 () {
    console.log('a1 start')
    await a2()
    console.log('a1 end')
}
async function a2 () {
    console.log('a2')
}
console.log('script start')
setTimeout(() => {
    console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
    console.log('promise1')
})
a1()
let promise2 = new Promise((resolve) => {
    resolve('promise2.then')
    console.log('promise2')
})
promise2.then((res) => {
    console.log(res)
    Promise.resolve().then(() => {
        console.log('promise3')
    })
})
console.log('script end')

最后输出的顺序是:

script start
a1 start
a2
promise2
script end
promise1
a1 end
promise2.then
promise3
setTimeout

我的问题在于最后promise3 和 setTimeout究竟谁先输出。从代码中看到,promise3这个输出,是在执行promise2.then这个微任务的时候,通过Promise.resolve().then加入微任务队列的。根据事件循环的执行机制,应该是一次性将所有队列中的微任务执行完,再执行下一个宏任务。那么这里的情况有些特殊,是在执行微任务的时候,加入了另一个微任务,(如果理解有误请指出),那么这时候,是会先去执行一个宏任务,即setTimeout,还是将新加入的微任务先执行完呢?

谢谢!

阅读 1.4k
2 个回答

微任务队列清空才会去执行宏任务,无论是什么时间加入的

setTimeout是宏任务,promise是微任务,js事件循环的逻辑是,执行渲染程序主任务,然后同步程序在这个过程中讲所有的微任务宏任务存起来然后执行所有的微任务, 然后执行一个宏任务, 然后查看是否有DOM更新, 如果有就更新DOM没有就执行所有微任务然后一个宏任务........等等.....
因此和加入的时间是没有关系的的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题