You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

给定异步代码场景,代码块的执行顺序及原因是什么?

const mainFun = async () => {
    const promise1 = asyncFun()
    const promise2 = asyncFun()
    const promise3 = asyncFun()

    await Promise.all([promise1, promise2, promise3])
}


const asyncFun = async () => {
    // 非异步计算,耗时1秒
    someCalculation()
    // 快速异步调用,耗时1毫秒
    await anotherAsyncFun()
    // 其他计算
    otherCalculation()
}

问题描述

忽略运行时长的现实差异,我原本预期执行流程为:

  1. 启动promise1,约1秒后遇到第一个await,等待期间寻找其他可执行代码
  2. 启动promise2,约1秒后遇到第一个await,等待期间寻找其他可执行代码
  3. 由于promise1的第一个await完成,继续执行otherCalculation
  4. [...]
    但实际测试发现直觉错误——代码会先启动promise3,而非回到promise1继续执行。我不确定该用何种术语描述这种类似“深度优先”或“广度优先”的逻辑,想请教这段代码的执行顺序是什么?以及背后的原因?

执行顺序与核心原因解析

实际执行流程

  1. 进入mainFun,首先执行const promise1 = asyncFun():
    • 立即进入asyncFun,同步执行someCalculation();
    • 遇到await anotherAsyncFun()时,暂停asyncFun执行,将后续的otherCalculation()包装成微任务,同时返回一个未完成的Promise给promise1;
    • 主线程回到mainFun,继续执行下一行同步代码。
  2. 主线程执行const promise2 = asyncFun():
    • 重复步骤1的过程,同步执行someCalculation(),遇到await后暂停,返回Promise给promise2,主线程回到mainFun。
  3. 主线程执行const promise3 = asyncFun():
    • 同样同步执行someCalculation(),遇到await后暂停,返回Promise给promise3,主线程回到mainFun。
  4. 主线程执行await Promise.all([promise1, promise2, promise3]),此时主线程挂起,等待所有传入的Promise完成。
  5. 当anotherAsyncFun()的Promise resolve后,对应的微任务会被加入微任务队列;若三个Promise几乎同时完成,微任务会按promise1→promise2→promise3的顺序依次执行,即依次调用otherCalculation()。

关键原因说明

  1. 同步代码优先执行:JavaScript是单线程模型,调用栈中的同步代码会被全部执行完毕,才会处理事件队列中的微任务/宏任务。mainFun中三个asyncFun()的调用属于同步操作,因此程序会先把每个asyncFun()的同步部分(someCalculation())依次执行完,不会在中途被异步任务打断。
  2. async/await的本质是Promise语法糖:await会暂停当前async函数的执行,将函数剩余逻辑注册为Promise的回调(微任务),但这个回调不会立即执行——必须等当前调用栈清空后,才会开始处理微任务队列。
  3. Promise.all不影响前置同步逻辑:Promise.all仅负责等待所有传入的Promise完成,不会改变前面三个asyncFun()的同步执行顺序,也不会提前触发微任务。

关于“深度/广度优先”的误区

这里并不适用深度或广度优先的描述,核心逻辑是同步执行优先级高于异步任务,以及调用栈的先进后出执行规则——主线程会先完成当前同步上下文的所有代码,再去处理异步任务队列。


内容的提问来源于stack exchange,提问作者oli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:31:58