事件循环(二)

27 阅读1分钟

六. 示例 1

async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2');
}
console.log('script start');
setTimeout(() => {
  console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {
  console.log('promise1');
  resolve();
}).then(function () {
  console.log('promise2');
})
console.log('script end');

// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout

开始一顿猛分析:

第一轮宏任务

  1. 定义 async1() 函数,未调用
  2. 定义 async2() 函数,未调用
  3. 执行 console.log('script start'),打印出 'script start'
  4. 遇到 setTimeout,属于宏任务,放到下一轮执行
  5. 调用 async1()函数,打印出 'async1 start'
  6. async1() 方法体内遇到执行 await async2() 函数,await 的作用相当于将后面的函数放入 new Promise 中,将之后后面的内容放到 .then() 中,比如:
await async2();
console.log('async1 end');

就相当于:

new Promise(async2(resolve, reject){
    resolve();
}).then(() => {
    console.log('async1 end');
})

所以执行 async2() 函数,并打印出 'async2', 同时将 console.log('async1 end') 放入微任务队列

  1. 遇到 new Promise 立即执行其方法体,打印出 'promise1', 并将 console.log('promise2')放入微任务队列
  2. 向下继续,执行 console.log('script end'),打印出 'script end'

至此,第一轮宏任务执行结束,打印结果为: 'script start'

'async1 start'

'async2'

'promise1'

'script end'

同时,微任务队列此时有以下两个微任务等待执行:

console.log('async1 end');

console.log('promise2');

执行微任务队列的全部微任务,打印出 'async1 end''promise2', 同时宏任务队列此时有:setTimeout

第二轮宏任务,宏任务队列目前只有 setTimeout

  1. 执行打印出 'setTimeout'

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

'script start'

'async1 start'

'async2'

'promise1'

'script end'

'async1 end'

'promise2'

'setTimeout'