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

Promise的then方法返回Promise对象时的执行顺序问题

问题解答

核心结论

console.log(4)输出在3之后,本质是**then回调返回Promise实例时,会触发额外的微任务调度流程,导致后续链式then的执行延后了2个微任务周期**。

测试代码

Promise.resolve().then(() => {
    console.log(0);
    return Promise.resolve(4);
}).then((res) => {
    console.log(res)
})

Promise.resolve().then(() => {
    console.log(1);
}).then(() => {
    console.log(2);
}).then(() => {
    console.log(3);
}).then(() => {
    console.log(5);
}).then(() =>{
    console.log(6);
})

执行流程拆解

JS中微任务队列遵循先进先出规则执行,按阶段拆解执行过程:

  1. 初始阶段:两个Promise.resolve()均为已决议状态,它们的第一个then回调依次入队,微任务队列:[打印0的回调, 打印1的回调]
  2. 执行第一个微任务:打印0,返回已决议的Promise.resolve(4)(记为p4)。此时触发规范定义的PromiseResolveThenableJob微任务入队,作用是绑定p4的决议结果到外层Promise。当前微任务队列:[打印1的回调, PromiseResolveThenableJob]
  3. 执行下一个微任务:打印1,回调无特殊返回值,下一个打印2的then回调直接入队。微任务队列:[PromiseResolveThenableJob, 打印2的回调]
  4. 执行PromiseResolveThenableJob:读取到p4的决议值为4,此时还需要再生成一个微任务,才能把4传递给外层Promise的下一个then回调,这个微任务入队。微任务队列:[打印2的回调, 触发打印4的微任务]
  5. 执行打印2的回调,无特殊返回值,打印3的回调入队。微任务队列:[触发打印4的微任务, 打印3的回调]
  6. 执行打印3的回调,无特殊返回值,打印5的回调入队。微任务队列:[触发打印4的微任务, 打印5的回调]
  7. 执行触发打印4的微任务:打印4。微任务队列:[打印5的回调]
  8. 依次执行后续微任务,打印5、6,最终输出顺序为0 1 2 3 4 5 6

then返回Promise的特殊处理逻辑

根据ECMAScript规范,then回调返回值会触发[[Resolve]]抽象操作,当返回值是Promise这类thenable对象时,会有特殊处理:

  • 不会直接用这个Promise的结果决议当前then返回的外层Promise
  • 会新增一个PromiseResolveThenableJob微任务入队,专门处理这个返回的Promise的决议逻辑
  • 等这个返回的Promise决议完成后,还需要再新增一个微任务,才能把决议结果传递给外层Promise的后续then回调
  • 整个流程比普通返回非thenable值的情况多了2次微任务调度,所以后续then的执行会延后2个微任务周期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:54:00