可在全局作用域监听unhandledrejection事件捕获未处理的promise拒绝:浏览器用window.addeventlistener('unhandledrejection'),node.js用process.on('unhandledrejection'),需早期注册、类型判断reason、避免依赖兜底而忽视显式错误处理。

可以在全局作用域(如浏览器的 window 或 Node.js 的 process)监听 unhandledrejection 事件,捕获未被 .catch() 或 try/catch 处理的 Promise 拒绝,避免静默失败。
浏览器中监听 window.unhandledrejection
在浏览器环境中,通过 window.addEventListener('unhandledrejection', ...) 监听该事件。事件对象包含 reason(拒绝原因,可能是 Error 实例或任意值)和 promise(触发拒绝的 Promise 实例)。
- 必须在 Promise 创建前或页面早期注册监听器,否则可能错过某些拒绝
- 调用
event.preventDefault()可阻止默认控制台警告(但不推荐长期屏蔽,仅用于自定义处理) - 常见用途:统一上报错误、记录日志、触发降级逻辑
示例:
Node.js 中监听 process.unhandledRejection
Node.js 使用 process.on('unhandledRejection', ...)。注意:从 Node.js 15 开始,未处理的 Promise 拒绝会触发 unhandledRejection 事件,且若未监听,进程将在后续版本中默认退出(v15+ 默认启用 --unhandled-rejections=throw)。
- 回调函数接收两个参数:
reason和promise,与浏览器一致 - 建议始终监听并至少记录日志,否则可能导致进程意外终止
- 可通过
process.setUncaughtExceptionCaptureCallback配合使用,但两者职责不同:前者专用于 Promise,后者用于同步异常
示例:
process.on('unhandledRejection', (reason, promise) => {console.error('Unhandled Rejection at:', promise);
console.error('Reason:', reason);
// 不调用 process.exit(),除非你明确要终止进程
});
注意事项与最佳实践
该事件是兜底机制,不是替代正确错误处理的方案。它只捕获“真正未处理”的拒绝——即没有链式 .catch()、没有 await 在 try/catch 中、也没有被其他 Promise 组合器(如 Promise.all)捕获的情况。
- 不要依赖它来掩盖疏忽;应优先在业务代码中显式处理拒绝
-
reason不一定是Error对象,可能是字符串、数字甚至undefined,需做类型判断 - 同一个 Promise 拒绝只会触发一次该事件;一旦被监听并处理,不会重复触发
- Vite / Webpack 等开发服务器可能自动注入监听器,生产环境仍需自行配置以确保可观测性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











