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

关于Promise执行顺序的疑问:为何输出‘1 2 11 22’而非‘1 2 22 11’?

为什么Promise链式调用的输出顺序是1 2 11 22而不是1 2 22 11?

嘿,这个问题其实是理解Promise微任务执行顺序的经典场景,我来一步步拆解给你看:

首先先贴下你的代码:

new Promise((res, rej) => { res(); })
 .then(() => {
 console.log(1);
 new Promise((res, rej) => { res(); })
 .then(() => { console.log(2); })
 .then(() => { console.log(22); });
 })
 .then(() => { console.log(11); });

要搞懂这个问题,核心是记住两个关键点:

  1. JavaScript事件循环里的微任务队列是按顺序逐个处理的,只有当前微任务执行完,才会去取下一个;
  2. Promise的then回调,必须等当前Promise的状态变为resolved后才会进入微任务队列,而且链式调用里的下一个then,必须等前一个then的回调执行完毕,才会被加入队列。

接下来我们一步步走执行流程:


1. 同步代码阶段

  • 创建第一个Promise,执行res(),这个Promise立刻变成resolved状态;
  • 调用它的第一个.then(),这个打印1的回调被加入微任务队列;
  • 同步代码执行完毕,开始处理微任务队列。

2. 处理第一个微任务(打印1的回调)

  • 先执行console.log(1),输出1;
  • 创建第二个Promise,执行res(),它也立刻变成resolved状态;
  • 调用第二个Promise的第一个.then(),这个打印2的回调被加入微任务队列;
  • 此时第二个Promise的第二个.then()(打印22)还进不了队列——因为它得等前一个then(打印2)执行完,这个Promise的状态才会因为前一个then的返回值变成resolved,才能触发下一个then的回调入队;
  • 第一个Promise的第一个then回调执行完了,它没有return值,JavaScript会自动把它包装成一个resolved状态的Promise,所以第一个Promise的第二个.then()(打印11)的回调被加入微任务队列。

现在微任务队列的顺序是:[打印2的回调, 打印11的回调]

3. 处理下一个微任务(打印2的回调)

  • 执行console.log(2),输出2;
  • 这个回调执行完后,第二个Promise的前一个then返回了undefined,被包装成resolved的Promise,所以第二个Promise的第二个.then()(打印22)的回调被加入微任务队列。

现在微任务队列的顺序是:[打印11的回调, 打印22的回调]

4. 处理下一个微任务(打印11的回调)

  • 执行console.log(11),输出11。

5. 处理最后一个微任务(打印22的回调)

  • 执行console.log(22),输出22。

这样走下来,最终的输出顺序就是1 2 11 22啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:57:37