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

为何Promise.finally会晚于调用者的then执行?代码示例解析

为什么异步Promise代码输出是1 2 A而非1 A 2?

先看这段异步JavaScript代码:

const a = () => {
  return new Promise((resolve) => {
    resolve(1);
  });
};

const b = () => {
  return new Promise((resolve) => {
    a()
      .then((aR) => {
        console.log(aR);
        resolve(2);
      })
      .finally(() => {
        console.log("A");
      });
  });
};

const c = () => {
  b().then((bR) => {
    console.log(bR);
  });
};

c();

它的输出是1 2 A,而非直觉中的1 A 2。对比同步版本的代码:

const a = () => 1

const b = () => {
  try {
    const aR = a()
    console.log(aR)
    return 2
  } finally {
   console.log("A")
  }
};

const c = () => {
  try {
  const bR = b()
  console.log(bR)
  } catch {}
};

c();

这段同步代码的输出是1 A 2,两者差异的核心在于Promise的finally与同步try/finally的执行逻辑不同:

  • 同步逻辑中,try块里的return 2会先计算出返回值,但不会立刻返回函数,而是先执行finally块的代码,之后才把返回值传递给调用方。所以执行顺序是:打印1 → 执行finally打印A → 打印b()的返回值2。

  • 异步Promise逻辑中:

    1. a()的then回调执行时,先打印1,接着调用resolve(2)——这会把b()返回的Promise标记为已完成状态,同时将b().then(...)的回调加入微任务队列等待执行。
    2. then回调执行完毕后,a()的finally回调被加入微任务队列。
    3. 事件循环处理微任务队列时,会按队列顺序执行:先执行b().then的回调打印2,再执行finally的回调打印A,最终输出1 2 A。

简单总结:同步finally是在函数返回前执行,而Promise的finally是微任务,会排在resolve触发的外部Promise回调之后执行。

内容的提问来源于Stack Exchange,提问作者typed-sigterm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:25:14