Promise 的 then()
方法返回的新 Promise 对象具有以下关键特点,这些特点是实现链式调用的核心基础:
1. 全新的 Promise 实例
then()
返回的是一个全新的 Promise 对象,与调用它的原 Promise 没有引用关系。这意味着:
- 原 Promise 的状态变化不会直接影响新 Promise
- 链式调用中的每个
then()
都是基于新 Promise 进行的
2. 状态由回调函数的执行结果决定
新 Promise 的最终状态(成功/失败)和结果值,完全由 then()
中回调函数(onFulfilled
或 onRejected
)的执行结果决定,具体规则如下:
回调函数的执行情况 | 新 Promise 的状态 | 新 Promise 的结果值 |
---|---|---|
回调返回普通值(非 Promise) | 成功(Fulfilled) | 该普通值就是新 Promise 的结果 |
回调返回另一个 Promise 对象 | 继承该 Promise 的状态 | 继承该 Promise 的结果(成功值/错误) |
回调抛出错误(throw error ) |
失败(Rejected) | 抛出的错误对象就是新 Promise 的结果 |
示例:
const originalPromise = Promise.resolve(10);
// 情况1:回调返回普通值
const p1 = originalPromise.then(num => num * 2);
p1.then(result => console.log(result)); // 输出 20(新 Promise 成功,结果为 20)
// 情况2:回调返回 Promise
const p2 = originalPromise.then(num => Promise.resolve(num + 5));
p2.then(result => console.log(result)); // 输出 15(继承返回的 Promise 结果)
// 情况3:回调抛出错误
const p3 = originalPromise.then(() => {
throw new Error("出错了"); });
p3.catch(error => console.log(error.message)); // 输出 "出错了"(新 Promise 失败)
3. 默认状态为“待定(Pending)”
then()
返回的新 Promise 初始状态为 Pending,直到内部回调函数执行完成后,才会根据上述规则确定最终状态。
这意味着:链式调用中的后续 then()
会等待前一个 then()
的回调执行完毕,再处理新 Promise 的结果,从而实现异步操作的顺序执行。
4. 支持继续链式调用
由于 then()
返回的是 Promise 对象,因此可以继续调用 then()
或 catch()
,形成链式调用链条。
这种特性解决了“回调地狱”问题,让多步异步操作的逻辑可以线性书写:
fetchData()
.then(data => processData(data)) // 第一步处理
.then(processedData => saveData(processedData)) // 第二步处理(等待第一步完成)
.then(savedResult => showSuccess(savedResult)) // 第三步处理(等待第二步完成)
.catch(error => handleError(error)); // 捕获链条中任何环节的错误
5. 错误透传特性
如果前一个 then()
没有处理错误(即未提供 onRejected
回调),则错误会自动透传到下一个 then()
返回的新 Promise 中,直到被某个 catch()
捕获。
示例:
Promise.reject(new Error("原始错误"))
.then(
result => console.log(result), // 不处理错误(只提供了成功回调)
// 未提供失败回调,错误会透传
)
.then(
// 上一步透传的错误会直接进入当前 then() 的失败处理
null,
error => console.log("捕获错误:", error.message) // 输出 "捕获错误:原始错误"
);
总结
then()
返回的新 Promise 是实现链式调用的核心,它的状态完全由回调函数的执行结果决定,并且支持错误透传,这使得异步代码能够以清晰、线性的方式组织,大幅提升了代码的可读性和可维护性。