async函数外无法用try...catch捕获异常,因错误以Promise rejection形式存在;必须通过监听unhandledrejection事件兜底,或为每个Promise显式添加.catch()、await配合try...catch主动处理。

在 async 函数外无法直接用 try...catch 捕获其内部抛出的异常,因为 async 函数返回的是 Promise,错误会以 rejection 形式存在。要处理这些未捕获的 Promise 异常,关键在于监听全局 Promise 拒绝事件或确保所有 Promise 都被正确链式捕获。
监听 unhandledrejection 事件
这是最常用且推荐的方式,用于捕获所有未被 .catch() 或 await 处理的 Promise rejection:
- 浏览器和 Node.js(v15+)都支持
window.addEventListener('unhandledrejection')(浏览器)或process.on('unhandledRejection')(Node.js) - 该事件只触发一次,且仅当 rejection 确实未被处理时才触发(比如忘记加
.catch()或await后没包 try/catch) - 注意:它不能阻止错误发生,只能做日志、上报或降级处理,不能“恢复”Promise 状态
示例(浏览器):
window.addEventListener('unhandledrejection', event => {console.error('未处理的 Promise 错误:', event.reason);
event.preventDefault(); // 阻止默认控制台警告(可选)
});
避免依赖全局监听,主动处理每个 Promise
全局监听是兜底手段,但健壮的应用应尽量在源头处理错误:
立即学习“Java免费学习笔记(深入)”;
- 所有
async函数调用后,要么用await并包裹在try...catch中,要么显式调用.catch() - 对多个并发 Promise(如
Promise.all),需注意:只要其中一个 reject,整个 Promise 就失败;可用Promise.allSettled避免连锁失败 - 避免“fire-and-forget”模式:比如写了
doAsyncTask();却不处理它的返回值,这极易导致 unhandled rejection
Node.js 中的额外注意事项
Node.js 对未处理 rejection 更严格(尤其 v15+ 默认会打印警告并可能终止进程):
- 必须监听
process.on('unhandledRejection'),否则可能触发进程退出(取决于版本和配置) - 可以配合
process.on('rejectionHandled')跟踪是否后来补上了 catch(较少用,主要用于调试) - 某些库(如 Mocha、Jest)会自动处理测试中的 Promise,但生产代码仍需自行保障
开发阶段辅助检测
利用工具提前暴露问题:
- 启用 ESLint 规则如
no-promise-without-catch或require-await,提示遗漏错误处理 - Chrome DevTools 和 VS Code 的调试器会在 Sources 面板中标记 unhandled rejection
- 单元测试中模拟 Promise rejection,验证错误路径是否被覆盖


















