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

Promise链式调用中microtasks queue任务顺序疑问

疑问:Promise微任务队列的执行顺序问题

我不理解任务被送入microtasks queue的顺序。我预期的输出为:1, 11, 111, 2, 3, 12, 122,但实际得到的输出是:1, 11, 111, 2, 12, 122, 3。请问编译器是会注册整个Promise链,还是仅能识别下一个then?这一机制具体是如何运作的?

对应的代码如下:

Promise.resolve()
  .then(() => console.log(1))
  .then(() => console.log(2))
  .then(() => console.log(3));

Promise.resolve()
  .then(() => console.log(11))
  .then(() => console.log(12));

Promise.resolve()
  .then(() => console.log(111))
  .then(() => console.log(122));

机制解释

首先明确:JavaScript引擎不会预先注册整个Promise链,每个then的回调只会在前一个Promise完成(决议)后,才会被添加到微任务队列中。具体执行流程如下:

  1. 初始微任务队列填充:
    三个Promise.resolve()会立即进入已决议状态,它们的第一个then回调会按照代码书写顺序依次被加入微任务队列。此时队列顺序为:[输出1的回调, 输出11的回调, 输出111的回调]。

  2. 第一轮微任务执行:
    事件循环开始处理微任务队列,依次执行三个回调,输出1、11、111。

  3. 链式回调的添加逻辑:
    每个then执行完毕后,会返回一个新的已决议Promise(因为回调没有返回异步值),此时这个新Promise绑定的下一个then回调会被加入微任务队列:

    • 执行完输出1的回调后,输出2的回调被加入队列;
    • 执行完输出11的回调后,输出12的回调被加入队列;
    • 执行完输出111的回调后,输出122的回调被加入队列;
      此时微任务队列更新为:[输出2的回调, 输出12的回调, 输出122的回调]。
  4. 第二轮微任务执行:
    依次执行队列中的回调,输出2、12、122。

  5. 最后一个回调的添加与执行:
    执行完输出2的回调后,它返回的新Promise会触发第三个then的输出3回调加入队列,此时队列中只有这个回调,执行后输出3。

这就是为什么实际输出顺序是1, 11, 111, 2, 12, 122, 3,而非你预期的顺序——你错误假设了整个Promise链的回调会被一次性加入队列,但实际上它们是在前一个步骤完成后才被逐步添加的。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:23:14