js Promise 和 setTimeout 的顺序

new Promise((resolve, reject) => {
  resolve()
}).then(() => {
  console.log(1)
  new Promise((resolve, reject) => {
    resolve()
  }).then(() => {
    console.log(2)
  })
  setTimeout(() => { console.log(3) }, 0)
})

console.log(4)

setTimeout(() => { console.log(5) }, 0)

// 4
// 1
// 2
// 5
// 3

为什么2比5先打印?第一次 macrotask queue 执行完后将 microtask queue 中的 Promise.then 中的函数推出执行,执行结束后不是应该调用 macrotask queue 中的 setTimeout 么?为什么 .then 中的 Promise 先执行了。

阅读 2k
3 个回答

检查microtask queue,有promise回调要处理,出队并执行p1回调,执行回调的过程中往microtask queue添加promise,这是第一轮检查。继续检查microtask queue,发现p2回调,出队执行,第二轮结束。
检查macrotask queue

microtask queue里有两个 Promise 回调,都跑完了才能走下一个macrotask queue

new Promise((resolve, reject) => {
  setTimeout(()=>{resolve()},100);
}).then(() => {
  console.log(1)
  new Promise((resolve, reject) => {
    resolve()
  }).then(() => {
    console.log(2)
  })
  setTimeout(() => { console.log(3) }, 0)
})

console.log(4)

setTimeout(() => { console.log(5) }, 0)

你这样写5肯定会在2前面。你现在的代码写法 基本相当于同步了,从上到下执行,只有setTimeout是根据加入队列的顺序再执行的。 是说相当于哈,先打印出来是因为then的优先级高于setTimeout

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