async/await 不改变错误传递本质,但使异常路径更可控;await 触发的 reject 转为同步抛出,由最近 try/catch 捕获或作为 promise rejection 向外传递,未 await 的调用会导致错误隐身。

async/await 本身不改变错误传递的本质,但让异步链中的异常传递路径更可控、更贴近同步逻辑。关键在于理解 await 触发的 reject 会转为同步抛出,而错误最终落点取决于你是否捕获、何时捕获、以及 Promise 是否被 await。
错误从 await 处“冒泡”进 try/catch
当 await 后的 Promise 被 reject,JavaScript 引擎会立即将其转换为一个同步错误,中断当前 async 函数执行,并跳转到最近的 catch 块:
- 这个 throw 发生在 async 函数内部,所以能被同作用域的 try/catch 捕获
- 如果没写 try/catch,错误会作为该 async 函数返回的 Promise 的 rejection 向外传递
- 错误不会自动跨函数边界传播——必须通过 await 或 .catch() 显式接收
未 await 的调用会导致错误“隐身”
在 async 函数中调用另一个 async 函数却忘记加 await,是常见陷阱:
- 该调用立即返回 Promise,但内部可能已 reject
- 这个 rejection 不会触发当前函数的 catch,也不会中断后续代码执行
- 控制台出现 “Unhandled promise rejection”,但你的 try/catch 完全没运行
- 本质是 Promise 被创建却无人监听,错误被丢弃
错误传播终点由消费方式决定
async 函数返回的 Promise 是错误传递的载体,你如何使用它,就决定了错误最终在哪处理:
- 在函数内部用 try/catch:错误止步于当前层,适合做重试、降级或转换
- 在外部调用时链式 .catch():错误交由上层统一处理,利于日志聚合或全局 UI 提示
- 内外结合:内部捕获可预期错误(如网络超时),外部 .catch() 拦截兜底异常
多个 await 的精细化错误控制
不必把所有 await 塞进同一个 try 块。更灵活的做法是让每个异步操作独立承担错误责任:
- 用
.catch()直接附在单个 Promise 后,返回默认值或 null - 例如:
const data = await fetchData().catch(() => null); - 避免一个环节失败导致整个流程中断,也减少 try/catch 嵌套
- 适合并行请求、非关键依赖等场景











