当 Promise 的 then()
方法返回的新 Promise 状态为 失败(Rejected) 时,链式调用会遵循“错误冒泡”机制,具体执行规则如下:
1. 直接触发下一个 then()
的失败回调(若提供)
如果链式调用的下一个 then()
提供了第二个参数(onRejected
失败回调),则该回调会被立即触发,接收当前失败的原因作为参数。
示例:
Promise.resolve()
.then(() => {
// 第一个 then() 返回失败的新 Promise
return Promise.reject(new Error("操作失败"));
})
.then(
// 成功回调(不会执行,因为前一个 Promise 失败)
() => console.log("这里不会执行"),
// 失败回调(会执行,接收错误原因)
(error) => {
console.log("捕获错误:", error.message); // 输出:捕获错误:操作失败
return "错误已处理"; // 返回普通值,新 Promise 变为成功状态
}
)
.then((result) => {
// 前一个 then() 已处理错误,状态变为成功,这里会执行
console.log("后续操作:", result); // 输出:后续操作:错误已处理
});
2. 若下一个 then()
未提供失败回调,错误会“冒泡”传递
如果下一个 then()
只提供了成功回调(或未提供任何回调),则失败状态会跳过当前 then()
,继续向后传递,直到遇到第一个提供失败回调的 then()
或 catch()
。
示例:
Promise.resolve()
.then(() => {
throw new Error("原始错误"); // 返回失败的新 Promise
})
.then((result) => {
// 未提供失败回调,错误会跳过当前 then()
console.log("这里不会执行");
})
.then(
(result) => console.log("这里也不会执行"), // 继续跳过
(error) => {
// 遇到提供失败回调的 then(),触发执行
console.log("最终捕获:", error.message); // 输出:最终捕获:原始错误
}
);
3. catch()
本质是 then(null, onRejected)
,会捕获冒泡的错误
catch()
方法是 then(null, onRejected)
的语法糖,专门用于捕获错误。当失败状态冒泡到 catch()
时,会触发其回调函数。
示例:
Promise.resolve()
.then(() => {
return Promise.reject(new Error("网络异常")); // 返回失败的新 Promise
})
.then((data) => {
// 未处理错误,错误继续冒泡
console.log("处理数据"); // 不会执行
})
.catch((error) => {
// catch() 捕获到冒泡的错误
console.log("错误处理:", error.message); // 输出:错误处理:网络异常
return "恢复正常"; // 返回成功结果,后续 then() 可继续执行
})
.then((result) => {
// catch() 处理后状态变为成功,这里会执行
console.log("继续操作:", result); // 输出:继续操作:恢复正常
});
总结
当 then()
返回的新 Promise 状态为失败时,链式调用会:
- 优先寻找下一个
then()
中的失败回调(第二个参数)进行处理; - 若未找到,则错误会一直“冒泡”,直到被某个
catch()
捕获; - 错误被处理后(回调正常返回结果),后续的
then()
会继续执行(基于新的成功状态)。
这种机制保证了异步操作中的错误能被集中处理,避免了代码中到处充斥错误处理逻辑,使链式调用更加简洁清晰。