在async/await机制中,依赖try/catch捕获Promiserejection,但无法直接处理传统回调中的异常。需要将回调函数封装成Promise对象,异常才能被await感知并捕获。并发场景下,Promise.all任一失败即整体reject;而Promise.allSettled需手动遍历结果检查每个状态,适用于需要分别处理的情况。
async/await 本身并不直接处理回调函数中的异常,它依赖 try/catch 来捕获 await 表达式抛出的 Promise rejection。关键点在于:只有被 await 的 Promise 被 reject 时,错误才会进入 catch;而传统回调函数(例如 fs.readFile 的回调)内部的异常,根本不会被 try/catch 逮到——除非先将回调 Promise 化。

因此,async/await 的核心机制是:它不会自动捕获回调函数中的 throw,只关心 await 后面的 Promise 是否被 reject。如果仍在使用原始回调(如 setTimeout 或 fs.readFile 的 err-first 风格),其中的异常会像幽灵一样直接逃逸出 try/catch 的作用域。只有将回调包装成 Promise,await 才能感知到错误,进而被外层的 catch 捕获。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
要让 await 和 try/catch 在回调场景下生效,必须先将原始回调封装成 Promise。具体操作如下:
util.promisify,或封装一个可复用的 promisify 函数,省心省力。catch 只捕获当前 await 所等待的 Promise 的 rejection,而不是整个 async 函数体内任意抛出的异常。这一点容易踩坑:
await someAsync(); throw new Error('oops'); —— 这个 throw 不会被外层 catch 捕获,除非它发生在 await 之后且未被处理。如果在 async 函数中直接使用传统回调(例如 setTimeout(() => { throw 'boom' }, 100)),该异常会完全脱离 try/catch 的作用域,变成未捕获异常(Uncaught Exception),轻则触发 unhandledrejection 事件,重则直接 crash 进程。解决办法:
当使用 Promise.all 或 Promise.allSettled 时,异常行为截然不同,选对工具很重要:
Promise.all([p1, p2]):任一 Promise reject,整个 all 就 reject,可以被外层 catch 统一捕获。Promise.allSettled([p1, p2]):总会 resolve,结果数组里包含每个 Promise 的 status 和 value/reason,需要手动遍历检查每个项是否 fulfilled。侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述