关于 Event Loop 中 async/await 的表现

前言

文关于 Event Loopasync/await 的表现,文章中表述的观点,纯属个人的一些猜测与验证,如有不对,敬请斧正。

猜测1

由于 微任务 是后加入到 任务队列 中的,且 Promise 也属于 微任务,那么大胆猜测, async/await 的异步任务,也属于微任务。

console.log(111);

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

(async () => {
  console.log(333);
  await console.log(444);
  console.log(555);
})()
  .then(()=>{
    console.log(666);
  });

console.log(777);

// 执行结果
// 111
// 333
// 444
// 777
// 555
// 666
// 222

分析

  1. setTimeout 在 async 的上面,但是它最后执行,表明 async/await 的异步属于 微任务
  2. async 函数,会被包装成 Promise ,所以 console.log(6) 这一块的代码,也是 微任务;
  3. Promise 相同,在执行 async 函数时,在遇到 await 之前,均是同步的代码;

疑问:

await 后面的代码是怎样执行的?再遇到下一个 await 又是怎样的?

猜测2

await 后面的代码,async 中 执行到的 await 后的代码是被当成一个整体来看的,这个整体属于一个 微任务

console.log(111);

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

(async () => {
  console.log(333);
  await console.log(444);
  console.log(555);

  await console.log(666);
  console.log(777);
})()
  .then(()=>{
    console.log(888);
  });
console.log(999);

new Promise((resolve) => {
  resolve();
})
  .then(() => {
    console.log('promise');
  });

// 执行结果
// 111
// 333    
// 444    
// 999    
// 555    
// 666    
// promise
// 777    
// 888    
// 222

分析

从当前结果看, 999 之前的应该没有疑问,都是同步代码,需要考虑的时 await 后的代码执行逻辑。

  1. 先将代码拆分成块:
// awaitA 代码块      --- 执行了第一个 await 后面的代码
console.log(555);
await console.log(666);
console.log(777);

// awaitB  代码块     --- 执行了第二个 await 后面的代码
console.log(777);

// async.then 代码块  --- async 的 .then 代码块,它需要等到  async 函数执行完成。
.then(()=>{
  console.log(888);
});

// promise 代码块
new Promise((resolve) => {
  resolve();
})
  .then(() => {
    console.log('promise');
  });
  1. 分析过程:
    由上面的结论,现在得到任务队列中的有四个任务:
    • awaitA 代码块 — 微任务;
    • async.then 代码块 — 微任务;
    • promise 代码块 — 微任务;
    • setTimeout — 宏任务;

先执行微任务:
按照 微任务先进先出 规则,

执行 awaitA 代码块,打印 555, 666,此时,又遇到一个 await, 则将第二个 await 后面的代码,也就是 awaitB 代码块 追加到 微任务 中;

继续执行 微任务,此时执行 promise 代码块,打印 promise

由于 async.then 代码块 这块比较特殊,它时等 async 执行完成后,才会被添加到队列中的,所以此时它还没有添加到队列中,所以现在执行第二个 await 后的代码块,也就是 awaitB 代码块, 此时打印 777;

async 函数中的代码执行完成后,async.then 代码块 的代码添加到微任务队列并执行,打印 888;

最后在执行 setTimeout,打印222.

结论:

asyncEvent Loop 中,遇到 await 之前的代码,都属于同步代码,当遇到第一个 await 后,属于 aysnc 函数中的 await 后面的所有代码,都作为一个微任务,保存到任务队列中,当执行完成同步代码后,执行任务队列中的微任务

当执行 await 后面的 微任务 代码块时,如果内部还有 await ,后面的代码再继续被添加到 微任务队列 中,由于 微任务 的特性,所有 微任务 都执行完成后,再去执行 宏任务,所以才会出现上面的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值