
`unhandledrejection` 是浏览器中全局触发的 dom 事件,用于通知开发者存在未被 `catch()` 或 `try/catch` 捕获的 promise 拒绝;它**不会中断脚本执行**,仅提供调试与监控能力。
在 JavaScript 中,unhandledrejection 事件并非发生在“变量作用域”(scope)上——这是一个容易引起误解的术语。实际上,它是一个标准的 DOM 事件,始终派发(dispatched)到全局对象:在浏览器主页面中是 window,在 Web Worker 中则是 self。这意味着你可以直接调用:
addEventListener('unhandledrejection', (event) => {
console.warn('⚠️ Unhandled rejection detected:', event.reason);
// 可选:阻止默认行为(如控制台警告),但不影响执行流
event.preventDefault();
});等价于显式写为:
window.addEventListener('unhandledrejection', …); // 浏览器环境
// 或
self.addEventListener('unhandledrejection', …); // Worker 环境这是因为 window 和 self 同时承担双重角色:既是事件目标(EventTarget),又是全局变量作用域的绑定对象(即 var x = 1 会成为 window.x)。但事件机制本身与词法作用域无关。
关键澄清:未处理的 Promise 拒绝不会导致脚本终止或页面卡死。例如以下代码会正常输出 'after promise':
addEventListener('unhandledrejection', (e) => {
console.log('Caught unhandled rejection:', e.reason);
});
Promise.reject('Oops! No catch');
console.log('after promise'); // ✅ 仍会执行这与 Node.js 行为有本质区别:在 Node.js 中,自 v15 起,未处理的 Promise 拒绝默认会触发 process.on('unhandledRejection'),若未监听则最终导致进程退出(FATAL ERROR: ... unhandled promise rejection);而浏览器中无论是否监听 unhandledrejection,主线程和 Worker 均持续运行,用户交互、定时器、网络请求等全部不受影响。
✅ 最佳实践建议:
- 在应用初始化阶段注册 unhandledrejection 监听器,用于日志上报或错误追踪;
- 切勿依赖该事件“挽救”错误逻辑——它仅用于可观测性,真正的错误处理应通过 .catch()、async/await + try/catch 显式完成;
- 在生产环境可调用 event.preventDefault() 抑制浏览器默认控制台警告(但需谨慎,避免掩盖真实问题);
- 注意:该事件不冒泡,也无法被 stopPropagation() 影响,且仅对“完全未处理”的拒绝生效(即既无 .catch(),也无 await 上下文中的 try/catch)。
总之,unhandledrejection 是一个诊断工具,而非执行控制机制。理解其全局事件本质与非阻塞性质,是构建健壮前端异步错误处理体系的基础。










