JS异步--async,await,promise,setTimeout 执行顺序

本文深入探讨JavaScript异步执行的顺序,涉及async函数、await关键字、Promise以及setTimeout。通过实例代码证明了当遇到await时,后续代码会被放入等待队列,而setTimeout会放在一个优先级较低的队列。在同步代码执行完毕后,按照队列顺序依次执行await、promise的then()和setTimeout。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

在JavaScript的异步代码执行时:

  1. 如果遇到await,就将await执行后,后面的代码放入等待队列(因为async和await的本质还是promise的运用,返回的是一个promise对象)。

    备注:async是generator的语法糖, 只是把generator的function后面的*换成了前面的async,把yield换成了await。运行原理是一样的,都是为了解决JS的异步操作问题,毕竟JS是单线程的。

  2. 如果遇到promise的then和catch,也同样放入等待队列,二者优先级相同,在同步代码结束后按照队列的先入先出原则执行。

  3. 如果遇到setTimeout的话,也是同样放在等待队列,但是是不同的等待队列,优先级低于await和promise。

代码证明:

async function async1() {
    console.log("async1 start");
    await  async2();  // 关键点1
    console.log("async1 end");
}
async  function async2() {
    console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
    // 关键点2
    console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
    console.log("promise1");
    // 关键点3
    resolve();
}).then(function () {
    console.log("promise2");
});
console.log('script end');

以上代码片段的执行结果为:

>"script start"
> "async1 start"
> "async2"
> "promise1"
> "script end"
> "async1 end"
> "promise2"
> "settimeout"

解释:

----------------------------------------- 同步代码部分 --------------------------------------------

  1. 代码运行从同步操作console.log("script start");开始,遇到setTimeout直接丢到等待队列的最末端(其实是另一个优先级较低的等待队列的队首,姑且认为是promise等待队列的最末端)。
  2. 执行async1函数,其中的console.log("async1 start");为同步代码,直接输出,然后遇到了await async2
  3. 进入async2函数内部,执行其中包含的同步代码console.log( 'async2');,在执行过后马上将await后面的代码全部放到promise等待队列中。
  4. 接着寻找同步代码,发现promise中的console.log("promise1");为同步代码,立即执行。然后发现这个promise后面紧跟真一个then(),不要犹豫直接将这个promise放入刚刚已经存放了await的等待队列中。
  5. 最后一个同步代码console.log('script end');被找到并执行。

----------------------------------------- 异步代码部分 --------------------------------------------

现在的异步代码等待队列中,包含await函数后面的所有代码,和promise的then()

  1. 先执行await async2后面的代码console.log("async1 end");
  2. 在执行promise中的then()中的resolve代码console.log("promise2");
  3. 最后执行setTimeout代码console.log("settimeout");

√到此为止所有代码执行完毕。

来源:https://juejin.cn/post/6844903942057525261
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值