异步任务执行顺序

异步任务执行顺序

console.log(1);

async function foo() {
  console.log(2);
  await bar(); // 关键点:await 会暂停 foo 的执行
  console.log(3); // 被放入微任务队列(在 bar 的 Promise 解决后)
}

async function bar() {
  console.log(4);
  await Promise.resolve(); // 暂停 bar 的执行
  console.log(5); // 被放入微任务队列
}

setTimeout(() => console.log(6), 0); // 宏任务

foo();

new Promise(resolve => {
  console.log(7);
  resolve();
}).then(() => console.log(8)); // 微任务

console.log(9);

执行步骤详解:

  1. 同步代码执行

    • console.log(1) → 输出 1
    • 调用 foo()
      • console.log(2) → 输出 2
      • 调用 bar()
        • console.log(4) → 输出 4
        • await Promise.resolve() 暂停 bar,将 console.log(5) 放入微任务队列
      • await bar() 暂停 foo,将 console.log(3) 标记为等待(但尚未入队)
    • new Promise 同步执行:
      • console.log(7) → 输出 7
      • resolve() → 将 console.log(8) 放入微任务队列
    • console.log(9) → 输出 9
    • 当前输出:1, 2, 4, 7, 9
  2. 微任务队列处理

    • 微任务队列初始内容:[输出5, 输出8]
    • 执行第一个微任务:console.log(5) → 输出 5
      • 关键:此时 bar() 的 Promise 解决,触发 foo() 的等待结束
      • foo() 中的 console.log(3) 被放入微任务队列
    • 执行第二个微任务:console.log(8) → 输出 8
    • 执行第三个微任务:console.log(3) → 输出 3
    • 输出:5, 8, 3
  3. 宏任务队列处理

    • 执行 setTimeout 回调:console.log(6) → 输出 6

最终输出顺序:

1 → 2 → 4 → 7 → 9 → 5 → 8 → 3 → 6

关键机制说明:

  1. await 的双重暂停

    • await bar() 暂停 foo 时,console.log(3) 不会立即入队
    • 必须等待 bar() 的 Promise 解决(即 console.log(5) 执行后),console.log(3) 才加入微任务队列
  2. 微任务执行顺序

    微任务队列初始化
    微任务队列初始化
    触发foo继续
    同步代码
    输出5
    输出8
    输出3
  3. 优先级规则

    • 同步代码 > 已存在的微任务 > 新生成的微任务 > 宏任务
    • 微任务队列按 先进先出 (FIFO) 顺序执行

常见误区:

  • 误认为 await 后的代码会立即入队(实际需等待右侧 Promise 解决)
  • 忽略链式微任务的动态生成(如 console.log(3)console.log(5) 执行后才入队)
  • 混淆微任务和宏任务的优先级(微任务总是优先于宏任务)

你的理解完全正确!这个顺序展示了 JavaScript 事件循环的精细调度机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值