async函数内部未await的promise拒绝会触发unhandledrejection事件,必须用try/catch包裹await、避免漏await、全局监听兜底并慎用.catch()链式处理。

在 JavaScript 中,async 函数内部抛出的错误或未 await 的 Promise 拒绝,若未被正确捕获,会变成“未处理的拒绝(unhandled rejection)”,触发 unhandledrejection 事件,并可能在控制台报错、影响调试,甚至在 Node.js 中导致进程退出(v15+ 默认行为)。关键在于:**async 函数本身不会自动捕获内部 Promise 的拒绝,必须显式处理**。
使用 try/catch 包裹 await 表达式
这是最直接、推荐的方式。只有被 await 的 Promise 被拒绝时,才会进入 catch 块;未 await 的 Promise 拒绝仍会泄漏。
- 确保所有可能失败的
await调用都处于try/catch作用域内 - 避免在
try中混写同步逻辑和异步调用,防止错误类型混淆 - 示例:
async function fetchData() {
try {
const res = await fetch('/api/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
console.error('获取数据失败:', err);
throw err; // 或返回默认值、重试等
}
}
避免“忘记 await”导致的隐式拒绝
常见陷阱:调用 async 函数但没 await,导致其返回的 Promise 在外部无人监听。
- 启用 ESLint 规则
no-floating-promises(TypeScript)或require-await+ 自定义检查,辅助发现漏 await 的调用 - 在顶层调用时,务必用
await或.catch()处理,例如:fetchData().catch(console.error) - 不要依赖函数内部的
try/catch来保护外部调用者——它只捕获函数体内的 await 错误,不拦截返回 Promise 的拒绝
全局兜底:监听 unhandledrejection(仅用于日志和降级)
不能替代局部错误处理,但可作为最后一道防线,防止应用崩溃或丢失错误上下文。
- 浏览器中监听:
window.addEventListener('unhandledrejection', event => { ... }) - Node.js 中监听:
process.on('unhandledRejection', (reason, promise) => { ... }) - 注意:仅用于记录、上报或清理资源;不应在此处“吞掉”错误而不响应,否则掩盖问题
- Node.js v15+ 默认将未处理拒绝视为致命错误,可通过
--unhandled-rejections=warn临时调整,但不建议长期绕过
谨慎使用 .catch() 链式处理(适用于非 await 场景)
当不使用 await,而是以 Promise 链方式调用时,必须显式接 .catch()。
- 错误写法:
someAsyncFn().then(...)—— 拒绝会被忽略 - 正确写法:
someAsyncFn().then(...).catch(...)或someAsyncFn().catch(...) - 注意:箭头函数中若返回 Promise,也需保证链路完整,例如:
arr.map(x => apiCall(x)).forEach(p => p.catch(handleErr))
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











