Promise 实例的 catch() 方法和 then() 方法的第二个参数(失败回调)都能处理异步操作的失败,但它们在错误捕获范围和使用场景上有明显区别:
1. 本质区别:错误捕获范围不同
then()的第二个参数(onRejected):
只能捕获当前 Promise 自身的失败(即上一个 Promise 直接抛出的错误),无法捕获自身成功回调(onFulfilled)中产生的错误。catch()方法:
本质是then(null, onRejected)的语法糖,但它能捕获整个链式调用中所有上游的错误,包括:- 前面 Promise 直接抛出的错误;
- 前面
then()的成功回调(onFulfilled)中抛出的错误。
2. 代码示例对比
示例 1:then() 的失败回调无法捕获自身成功回调的错误
Promise.reject(new Error("原始错误"))
.then(
// 成功回调(不会执行,因为上一个 Promise 失败)
() => console.log("成功回调"),
// 失败回调:只能捕获上一个 Promise 的错误
(error) => {
console.log("then的失败回调捕获:", error.message); // 输出:原始错误
throw new Error("在失败回调中新增的错误"); // 这里抛出的错误,当前then无法捕获
}
)
.then(
() => console.log("后续成功回调"), // 不会执行
(error) => {
console.log("后续then的失败回调捕获:", error.message); // 输出:在失败回调中新增的错误
}
);
示例 2:catch() 能捕获链式调用中所有上游错误
Promise.resolve()
.then(() => {
throw new Error("成功回调中抛出的错误"); // 这里的错误会被后续catch捕获
})
.catch((error) => {
console.log("catch捕获:", error.message); // 输出:成功回调中抛出的错误
throw new Error("在catch中新增的错误"); // 这里的错误会被下一个catch捕获
})
.catch((error) => {
console.log("下一个catch捕获:", error.message); // 输出:在catch中新增的错误
});
3. 使用场景区别
优先使用
catch()的场景:
大多数情况下,推荐用catch()统一处理错误,因为它能捕获链式调用中所有可能的错误(包括成功回调中意外抛出的错误),代码更简洁、容错性更强。fetchData() .then(data => { // 处理数据(可能意外抛错) if (!data) throw new Error("数据为空"); return processData(data); }) .then(processedData => saveData(processedData)) .catch(error => { // 统一处理所有错误:网络请求失败、数据处理失败、保存失败等 console.error("操作失败:", error.message); });使用
then()失败回调的场景:
当需要针对特定 Promise 的失败做单独处理,且不希望影响后续链式调用时(处理后可返回新结果让链条继续执行)。fetchData() .then( data => processData(data), // 仅处理fetchData的失败,不影响后续流程 error => { console.log("请求失败,使用默认数据"); return getDefaultData(); // 返回默认数据,让链条继续执行 } ) .then(data => saveData(data)) // 无论前面是成功还是失败处理,这里都会执行 .catch(error => { // 仅捕获processData或saveData的错误 console.error("处理或保存失败:", error.message); });
总结
| 特性 | then() 的失败回调(第二个参数) |
catch() 方法 |
|---|---|---|
| 本质 | 仅处理当前 Promise 的直接失败 | then(null, onRejected) 的语法糖 |
| 错误捕获范围 | 只能捕获上一个 Promise 的失败 | 能捕获链式调用中所有上游错误(包括成功回调中的错误) |
| 适用场景 | 特定 Promise 的单独失败处理 | 统一捕获整个链条的所有错误 |
实际开发中,catch() 因更全面的错误捕获能力,使用频率更高;then() 的失败回调则适合针对性处理特定环节的错误。