60 秒回答模板

Promise.then 返回的是一个新的 Promise,不是原来的 Promise。onFulfilled 或 onRejected 返回普通值时,新 Promise fulfilled,值就是返回值;回调里抛异常时,新 Promise rejected,原因是这个异常;回调返回另一个 Promise 或 thenable 时,新 Promise 会采用它最终的状态和值。如果 then 没有传对应回调,fulfilled 的值或 rejected 的原因会向后穿透。正因为 then 每次都生成新 Promise,才能链式串起同步返回、异步等待和错误传播。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

先明确返回新 Promise

p.then(fn) 的返回值是新 Promise。原 Promise 的状态一旦确定不会再变,链式调用靠新 Promise 承接下一步结果。

02

普通返回值会变成 fulfilled

回调 return 1、return 'ok' 或不写 return,都会让 then 返回的新 Promise fulfilled;不写 return 的值是 undefined。

03

抛异常会变成 rejected

回调执行期间 throw error,等价于返回的新 Promise 被 reject。后续可以通过 catch 或第二个 then 参数捕获。

04

返回 Promise 会被展开

如果回调 return fetch() 或 return Promise.resolve(x),外层新 Promise 不会 fulfilled 成一个 Promise 对象,而是等待这个 Promise 的最终状态。thenable 也会按类似规则解析。

05

值穿透和错误穿透

then 没传 onFulfilled 时,成功值会继续传给后面的 then;没传 onRejected 时,拒因会继续向后传,直到被 catch 或 onRejected 捕获。

06

链式错误处理要谨慎

catch 本质也是 then(null, onRejected),catch 返回普通值会把链路恢复为 fulfilled;如果想继续失败,要重新 throw 或返回 rejected Promise。

易错点

  • 说 then 返回原 Promise,解释不了为什么链式调用每一步能拿到不同返回值。
  • 认为 then 回调返回 Promise 时下一步拿到的是 Promise 对象,而不是等待后的值。
  • catch 里吞掉错误后忘记重新 throw,导致后续链路误以为成功。
  • 不传 onRejected 时以为错误会消失,实际上拒因会继续向后穿透。

面试官追问

then 返回原 Promise 会有什么问题?

如果返回原 Promise,链式调用无法让每一步拥有自己的结果和错误状态,也无法表达回调返回值对下一步的影响。

then 里 return Promise.resolve(1) 和 return 1 区别是什么?

最终下一步拿到的值都是 1。区别是前者会经过 Promise 解析和等待流程,后者直接让新 Promise fulfilled。

catch 后面的 then 为什么还能执行成功回调?

如果 catch 捕获错误后返回普通值,它返回的新 Promise 会变成 fulfilled,后续 then 的成功回调就会执行。

then 第二个参数和 catch 有什么差异?

then(onFulfilled, onRejected) 的 onRejected 只能捕获前一个 Promise 的拒因,捕不到同一个 then 中 onFulfilled 抛出的异常;后接 catch 可以捕获前面链路抛出的异常。