最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
async await 怎么捕获异步回调函数中的异常
时间:2026-07-12 10:51:56 编辑:袖梨 来源:一聚教程网
async/await 通过 try/catch 捕获 await 的 Promise rejection,而非回调内 throw;需将回调(如 fs.readFile)Promise 化(如 util.promisify)才能被正确捕获;裸回调中的异常会逃逸为未捕获异常;Promise.all 遇拒即退,allSettled 则需手动检查结果。
async/await 本身不直接处理回调函数中的异常,而是通过 try/catch 捕获 await 表达式抛出的错误。关键在于:只有被 await 的 Promise 被 reject,错误才会进入 catch;而回调函数(如 setTimeout、Node.js 的 fs.readFile 回调)若未被 Promise 化,其内部异常不会自动被 try/catch 捕获。
确保回调函数被正确 Promise 化
原始回调函数(如 Node.js 的 err-first 风格)需封装为 Promise,才能让 await 和 try/catch 生效:
- 用 Promise 构造器包装:将回调的 error 参数转为 reject,成功结果转为 resolve
- 避免在回调里直接 throw —— 这只会触发未捕获异常,不会中断 await 流程
- 推荐使用现成工具(如 util.promisify)或封装可复用的 promisify 函数
正确使用 try/catch 包裹 await 表达式
catch 只能捕获当前 await 所等待的 Promise 的 rejection,不是整个 async 函数体内的任意 throw:
- 错误写法:
await someAsync(); throw new Error('oops');—— 这个 throw 不会被外层 catch 捕获,除非它发生在 await 后且没被处理 - 正确写法:所有可能出错的异步操作都用 await,并置于 try 块中
- 多个 await 可共用一个 try/catch,也可各自独立处理
注意非 Promise 回调的“幽灵异常”
如果在 async 函数里直接使用传统回调(比如 setTimeout(() => { throw 'boom' }, 100)),这个异常完全脱离 try/catch 作用域:
- 它会变成未捕获异常(Uncaught Exception),可能 crash 进程或触发 unhandledrejection 事件
- 解决方式:要么避免在 async 函数中裸写回调,要么手动用 try/catch 包裹回调内部逻辑(但不推荐,破坏 await 语义)
- 更安全的做法是把所有异步逻辑统一转为 Promise 链
处理多个并发异步操作的异常
使用 Promise.all 或 Promise.allSettled 时,异常行为不同:
-
Promise.all([p1, p2]):任一 Promise reject,整个 all 就 reject,可被外层 catch 捕获 -
Promise.allSettled([p1, p2]):总会 resolve,结果数组含每个 Promise 的 status 和 value/reason,需手动检查每个项是否 fulfilled - 若需部分失败仍继续,优先选 allSettled + 遍历结果判断
相关文章
- 哈啰出行免押金还要收费吗 07-12
- 《背包英雄》攻击模式分享 07-12
- 异环开荒攻略 异环新手入门全流程指南 07-12
- 三星Galaxy Z Flip3价格 07-12
- 《背包英雄》道具特质分享 07-12
- 抖音app苹果版在哪儿找-抖音app在App-Store怎么安装 07-12