async函数中promise拒绝必须显式处理,否则成未捕获rejection;应try/catch每个await、为“发射即忘”promise加.catch()、全局监听unhandledrejection兜底,并用eslint/ts提前预警。

async 函数里 Promise 拒绝不会自动中断执行,也不会被静默吞掉——它必须被显式处理,否则会变成未捕获的 rejection,触发全局警告甚至影响线上稳定性。核心原则就一条:拒绝必须有归属。
用 try/catch 包裹每个 await 表达式
这是最直接、最可控的错误捕获方式。await 本身不捕获错误,只是把 Promise 的 reject 转为可抛出的异常;只有放在 try 块里,才能被 catch 捕获。
- 每个可能失败的 await 都应独立包裹,尤其当后续逻辑依赖前一步结果时
- catch 中拿到的就是原始 reject 值(字符串、Error 实例或对象),无需解包
- 推荐统一 throw Error 实例,保留 stack 便于定位问题,避免 throw "xxx" 这类无堆栈写法
- 若某步失败后需降级或返回默认值,可在 catch 中 return,不必一定 re-throw
对“发射即忘”的 Promise 显式加 .catch()
有些异步操作确实不需要等待结果(比如上报日志、埋点),但绝不能放任其 rejection 无人处理。
- ❌ 错误:saveLog(data); —— Promise 创建后没 await、没 .then、没 .catch,reject 就成“未被等待的 promise”
- ✅ 正确:saveLog(data).catch(err => console.debug('log failed:', err));
- 如果业务允许失败且无需反馈,至少要 `.catch(() => {})`,避免触发 unhandledrejection
- 注意:不能靠外层 try/catch 捕获这种未 await 的 Promise 错误
全局监听 unhandledrejection 事件兜底
这是最后一道防线,用于发现遗漏的 rejection,不适合替代主动处理,但必不可少。
- 浏览器中:`window.addEventListener('unhandledrejection', event => { /* 上报或记录 */ })`
- Node.js 中:`process.on('unhandledRejection', (reason, promise) => { /* 日志或退出 */ })`
- 该事件只在 Promise reject 后完全无人监听(没 .catch、没 await、也没被 try/catch 捕获)时触发
- 开发阶段建议开启控制台提醒,生产环境建议接入监控系统
借助工具提前预警
光靠运行时捕获不够,静态检查能帮你在代码提交前发现问题。
- ESLint 插件如 `eslint-plugin-promise` 可检测 missing catch、await-for-promise 等常见疏漏
- TypeScript 能约束 Promise 类型、提示未处理的 Promise 返回值,减少隐式错误
- CI 流程中集成 lint 和类型检查,让“忘记 await”或“漏写 catch”在合并前就被拦截
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











