async/await 不改变异常传播本质但简化捕获路径,使异步错误可被 try/catch 直接捕获;await 后 promise 被拒绝时,引擎将其转为同步抛出错误并跳转至最近 catch;未 await 的 promise 错误会变成 unhandled rejection;错误最终落点取决于内部 try/catch 或外部 .catch() 处理方式。

async/await 不改变异常传播的本质,但显著简化了异步异常的捕获路径——它让异步错误能像同步错误一样被 try/catch 直接捕获,不再依赖 Promise 链中的 .catch() 逐层传递。
异常从 await 处“冒泡”进 try/catch
当 await 后的 Promise 被拒绝(reject),JavaScript 引擎会立即将该 rejection 转换为一个同步抛出的错误,并暂停当前 async 函数执行,跳转到最近的 catch 块。这相当于把异步失败“同步化”了。
- await 本身不抛错,但被 await 的 Promise 若 reject,就会触发 throw 行为
- 这个 throw 发生在 async 函数内部,所以能被同一作用域的 try/catch 捕获
- 如果没写 try/catch,错误会作为该 async 函数返回的 Promise 的 rejection 向外传递
未 await 的调用会导致异常“丢失”
若在 async 函数中调用了另一个 async 函数却忘了加 await,该调用会立即返回 Promise,而内部可能发生的错误不会中断当前函数流程,也不会被当前 try/catch 捕获。
- 错误仍存在于那个未 await 的 Promise 中,但无人监听 → 变成 unhandled rejection
- 主线程继续执行后续代码,看似“成功”,实则后台任务已失败
- 典型表现:控制台报 “Unhandled promise rejection”,但 catch 块完全没运行
错误传播终点取决于调用方式
async 函数返回的 Promise 本身仍是错误传播的载体。你选择如何消费它,决定了错误最终落点:
- 在内部用 try/catch:错误止步于函数体内,可做兜底、重试或转换
- 在外部链式调用 .catch():错误交由调用方统一处理,适合日志、监控或全局降级
- 两者结合:内部捕获特定错误(如网络超时),外部 catch 处理未预期异常
Promise 链与 await 的错误路径对比
Promise 链中,错误只能沿 then/catch 链向后传递;而 await + try/catch 把整个异步流程“拉平”,错误可在任意 await 步骤被截获,无需提前预设 catch 位置。
- Promise 链:错误必须流经每个 .then() 的 onRejected 参数或 .catch() 才能被捕获
- await 写法:一个 try/catch 就能覆盖多个 await,逻辑更集中、意图更明确
- 注意:await 并不能捕获 try 块外的同步错误(如变量未定义),它只响应 Promise rejection
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











