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 捕获。
原始回调函数(如 Node.js 的 err-first 风格)需封装为 Promise,才能让 await 和 try/catch 生效:
catch 只能捕获当前 await 所等待的 Promise 的 rejection,不是整个 async 函数体内的任意 throw:
await someAsync(); throw new Error('oops'); —— 这个 throw 不会被外层 catch 捕获,除非它发生在 await 后且没被处理如果在 async 函数里直接使用传统回调(比如 setTimeout(() => { throw 'boom' }, 100)),这个异常完全脱离 try/catch 作用域:
使用 Promise.all 或 Promise.allSettled 时,异常行为不同:
Promise.all([p1, p2]):任一 Promise reject,整个 all 就 reject,可被外层 catch 捕获Promise.allSettled([p1, p2]):总会 resolve,结果数组含每个 Promise 的 status 和 value/reason,需手动检查每个项是否 fulfilled