事件循环(三)

35 阅读1分钟

七. 示例 2:

console.log('start');
setTimeout(() => {
  console.log('children2');
  Promise.resolve().then(() => {
    console.log('children3');
  })
}, 0)
new Promise(function (resolve, reject) {
  console.log('children4');
  setTimeout(function () {
    console.log('children5');
    resolve('children6');
  }, 0)
}).then((res) => {
  console.log('children7');
  setTimeout(() => {
    console.log(res);
  }, 0)
})

// start
// children4
// children2
// children3
// children5
// children7
// children6

开始一顿猛分析

第一轮宏任务

  1. 执行 console.log('start'),打印出 'start'

  2. 遇到第一个 setTimeout,放到宏任务队列,等待执行

  3. 遇到 new Promise 直接执行方法体内的内容,执行 console.log('children4'),打印出 'children4',

    遇到第二个 setTimeout,放到宏任务队列,等待执行,

    注意:这时候还未调用 resolve(),所以 .then() 的内容无法放到微任务队列

第二轮宏任务:执行第一个 setTimeout

内容为:

console.log('children2');
Promise.resolve().then(() => {
    console.log('children3');
})
  1. 执行 console.log('children2'),打印出 'children2'
  2. 遇到 Promise,由于其方法体内没有内容,故没有代码执行,将 .then 的内容放到微任务队列里

此时此轮宏任务结束,开始执行微任务队列所有微任务; 微任务队列只有 console.log('children3'),执行并打印出 'children3'

第三轮宏任务:执行第二个 setTimeout

内容为:

console.log('children5');
resolve('children6');
  1. 执行 console.log('children5'), 并打印出 'children5'
  2. 并执行 resolve('children6'),将 .then() 后面的内容放到微任务队列中
  3. 执行微任务队列的所有微任务,此时微任务队列只有一个微任务:
console.log('children7');
setTimeout(() => {
    console.log(res);
}, 0)
  1. 执行 console.log('children7'),打印出 'children7'
  2. 遇到第三个 setTimeout,放到宏任务队列,等待执行

第四轮宏任务:执行第三个 setTimeout

内容为:console.log(res)

  1. 执行并打印出 ‘children6’

全部任务执行完成,打印顺序为:

'start'

'children4'

'children2'

'children3'

'children5'

'children7'

'children6'