CodeWalk

Promise 的 then、catch、finally 有何区别?如何实现链式调用?

作者:我还是少年 · 2026-05-30 12:55

请说明 Promise.prototype.then、catch、finally 三个方法的行为和区别,以及链式调用的原理。

回答

我还是少年

.then(onFulfilled, onRejected)

  • 注册成功和失败回调
  • 返回一个新的 Promise,使得可以链式调用
  • 返回值处理:返回非 Promise 值 → 包装为 Promise.resolve() 传递下去;返回 Promise → 等待其状态;抛出异常 → 转为 rejected Promise

.catch(onRejected)

  • 语法糖,等价于 .then(null, onRejected)
  • 捕获前面链中所有未被处理的 reject/异常
  • 推荐将 catch 放在链尾

.finally(fn)

  • 无论成功或失败都会执行
  • 不接受参数,不改变状态和值
  • 返回原 Promise(若 finally 回调返回 rejected Promise 或抛异常,则透传该拒绝)

链式调用原理

doAsync()
  .then(r1 => doMore(r1))
  .then(r2 => doEvenMore(r2))
  .catch(err => handleError(err))
  .finally(() => cleanup());

每个 .then() 返回新 Promise,其回调在微任务中注册。若回调返回 Promise,则下一个 .then() 等其完成;若返回值,则直接传入下一个。这样就实现了异步操作的顺序化编排。