async函数错误分同步和异步两类:同步错误(如参数校验、语法错误)可被外层try-catch捕获;异步错误(await Promise拒绝)须在await所在try块内捕获,漏写await或未处理会导致静默失败。

async 函数本身不会“构造错误”,但它的执行过程可能在两个关键环节抛出错误:一是函数定义或调用时的同步错误(如语法错误、参数校验失败),二是 await 等待 Promise 被拒绝(reject)时的异步错误。这两类错误必须用不同方式捕获。
同步阶段错误:函数调用即报错
这类错误发生在 async 函数被调用的瞬间,不涉及 await,比如:
- 传入非法参数导致立即 throw(如
if (!url) throw new Error("URL required")) - 函数体内同步代码异常(如访问 undefined 属性、JSON.parse 无效字符串)
- 语法错误或运行时 ReferenceError(通常在开发阶段暴露)
它们能被函数外部的 try-catch 直接捕获,因为此时函数尚未返回 Promise,还在同步执行栈中。
异步阶段错误:await 触发的 Promise 拒绝
这是最常见的“异步构造错误”,例如 fetch 失败、API 返回 500、timeout 超时等。关键点是:只有被 await 的 Promise 被 reject,才会转为可被内部 try-catch 捕获的异常。
- ✅ 正确:把 await 表达式写在 try 块内,错误进入 catch
- ❌ 错误:只对整个 async 函数外层套 try-catch,却没 await —— 这样 Promise 拒绝会静默丢失或触发 unhandledrejection
- ⚠️ 注意:漏写 await(如直接写
fetch(url)不加 await)会导致 Promise 未被等待,错误无法被捕获
多个异步操作的独立错误处理
当有多个无依赖的 await 调用时,不必全塞进一个 try-catch。可以分段包裹,避免一个失败阻断后续:
- 每个关键 await 单独用 try-catch,各自处理超时、网络、解析等不同错误类型
- 并行请求优先用
Promise.allSettled(),它不会因单个失败而中断,返回每个结果的状态对象 - 需要全部成功才继续时,用
Promise.all()并在外层 catch 统一处理
兜底防护:监听全局未捕获拒绝
即使写了 try-catch,仍可能遗漏某些 Promise(比如事件回调里的异步逻辑、第三方库未 await 的调用)。建议加一层防御:
- 在页面或应用初始化时监听
window.addEventListener('unhandledrejection', e => {...}) - 记录错误日志,避免静默失败影响用户体验和问题定位
- 注意:该监听仅作兜底,不能替代业务层的主动错误处理

















