- father::Promise对象
梗概
Promise 的 catch 方法用于处理 Promise 链中的错误,其返回值由传入的回调函数决定,可以返回正常值或抛出新的异常,这直接影响后续 Promise 链的执行流程。
语法
promise.catch(onRejected);其中 onRejected 是当 Promise 被拒绝(rejected)时调用的回调函数。
返回值规则
1. 回调函数返回普通值
当 catch 的回调函数返回一个普通值时,catch 方法会返回一个新的已解决(resolved)状态的 Promise,其值为回调函数的返回值。
Promise.reject('错误')
.catch(err => {
console.log('捕获到错误:', err);
return '恢复正常'; // 返回普通值
})
.then(value => {
console.log('继续正常流程:', value); // 输出: 继续正常流程: 恢复正常
});2. 回调函数返回 Promise
如果 catch 回调函数返回一个 Promise,catch 方法返回的 Promise 会跟随这个新 Promise 的状态。
Promise.reject('错误')
.catch(err => {
console.log('捕获到错误:', err);
return Promise.resolve('新的异步操作成功');
})
.then(value => {
console.log('继续正常流程:', value); // 输出: 继续正常流程: 新的异步操作成功
});3. 回调函数抛出异常
如果 catch 回调函数抛出异常,catch 方法返回的 Promise 会变为拒绝(rejected)状态。
Promise.reject('第一个错误')
.catch(err => {
console.log('捕获到错误:', err);
throw '第二个错误'; // 抛出新的异常
})
.catch(err => {
console.log('捕获到第二个错误:', err); // 输出: 捕获到第二个错误: 第二个错误
});实际应用
错误恢复
fetchData()
.catch(err => {
console.error('网络请求失败:', err);
return backupData; // 使用备用数据继续流程
})
.then(data => processData(data));错误转换
fetchData()
.catch(err => {
if (err.status === 404) {
throw new NotFoundError('资源不存在');
} else if (err.status === 403) {
throw new PermissionError('权限不足');
}
throw err; // 其他错误直接传递
})
.catch(err => {
if (err instanceof NotFoundError) {
// 处理特定类型的错误
} else {
// 处理通用错误
}
});条件分支处理
processTask()
.then(result => {
// 正常处理
return normalProcessing(result);
})
.catch(err => {
if (err.recoverable) {
// 可恢复错误,继续流程
console.warn('恢复处理:', err);
return alternativeProcessing();
}
// 不可恢复错误,重新抛出
throw err;
})
.then(finalResult => {
// 正常流程和可恢复错误流程都会到达这里
})
.catch(fatalErr => {
// 只有不可恢复的错误会到达这里
});最佳实践
- 总是在 Promise 链末尾添加 catch 处理器,避免未捕获的异常
- 在 catch 中明确返回一个值,以控制后续流程的行为
- 当需要中断流程时,使用 throw 抛出异常
- 根据业务逻辑需要,合理设计 catch 的位置(是在每个步骤后还是在整个流程末尾)
相关概念
- child::Promise对象 语法
- child::Promise的then方法
- child::async与await关键字
Promise的catch方法
.catch方法实际上就相当于.then(null, rejection)或.then(undefined, rejection),也就是then的第二个回调函数- 这是一种语法糖,提供了更清晰的错误处理方式
// 这两种写法是等价的
promise.then(onFulfilled, onRejected);
promise.then(onFulfilled).catch(onRejected);- 使用
.catch的好处是可以捕获前面then方法执行中的错误,更接近于同步的try/catch写法 - 另外,
.then方法中的错误会被”吃掉”(如果没有提供第二个参数),而.catch方法则可以捕获这些被”吞掉”的错误
// 推荐写法
promise
.then(function(data) {
// 处理成功结果
})
.catch(function(err) {
// 处理前面可能出现的错误
});示例
const promise = new Promise((resolve, reject) => {
reject(new Error('出错了'));
});
// 方式1:使用then的第二个参数
promise.then(
result => console.log('成功:', result),
error => console.log('失败:', error)
);
// 方式2:使用catch方法(推荐)
promise
.then(result => console.log('成功:', result))
.catch(error => console.log('失败:', error));