Promise 的异常捕获依赖 catch,仅处理链中 reject 和异步抛错,不捕获同步错误或未返回 Promise 的错误;需显式 return 异步操作,否则错误丢失;全局 unhandledrejection 仅用于监控,async/await 中用 try/catch 更直观。

Promise 的异常捕获主要靠 catch,但它只捕获“异步执行过程中抛出的错误”以及前序 Promise 链中被 reject 的情况,**不会捕获同步代码中的 try-catch 外部错误,也不会自动捕获未返回的 Promise 中的错误**。
catch 捕获的是 Promise 链中的 rejection
catch 实际上是 .then(undefined, onRejected) 的语法糖,它只响应当前 Promise 实例或上游 Promise 的 reject 状态:
- 如果前面的
then回调里 throw new Error(),会触发后续catch - 如果前面的
then回调里 返回一个被 reject 的 Promise(如Promise.reject(new Error('xxx'))),也会被catch捕获 - 但如果在
then内部写了一个没return的 Promise(比如忘记return fetch(...)),错误就丢失了,catch拦不到
常见漏捕场景:忘记 return 异步操作
下面这段代码的错误不会被 catch 到:
Promise.resolve()
.then(() => {
// ❌ 错误:没 return,fetch 的 rejection 不会进入链式流程
fetch('/api').catch(err => console.error('这里吞掉了错误'));
})
.catch(err => console.log('这个 catch 永远收不到 err')); // ← 不会执行
✅ 正确写法是显式 return Promise:
立即学习“Java免费学习笔记(深入)”;
Promise.resolve()
.then(() => {
// ✅ 返回 Promise,它的 rejection 会往下传
return fetch('/api').then(r => r.json());
})
.catch(err => console.log('现在能捕获网络或解析错误了'));
全局兜底:unhandledrejection
对于漏掉处理的 rejected Promise(比如没写 catch、或 catch 后又 throw 新错误但没再接),浏览器和 Node.js 提供了全局事件:
- 浏览器:
window.addEventListener('unhandledrejection', e => { ... }) - Node.js:
process.on('unhandledRejection', (reason, promise) => { ... })
这不能替代链式 catch,而是最后的监控和日志手段,**不用于业务逻辑恢复**。
async/await 中的错误捕获更直观
用 async/await 时,可以配合 try/catch 捕获 Promise rejection,语义更清晰:
async function loadData() {
try {
const res = await fetch('/api');
const data = await res.json();
return data;
} catch (err) {
// ✅ 捕获 fetch 失败、json 解析失败等所有 rejection 和 throw
console.error('加载失败:', err);
}
}
注意:await 后面必须是 Promise,否则 catch 捕不到;且函数本身要声明为 async,否则 await 无效。


















