async函数能用try/catch统一捕获同步错误和await的promise拒绝,普通函数只能捕获同步错误;前者必须配合promise语义处理,后者返回的rejected promise需调用方手动.catch()或await处理。

async 函数和普通函数在错误处理上的核心差异在于:普通函数只能捕获同步错误,而 async 函数能统一捕获同步错误和 await 等待的 Promise 拒绝(rejection),且必须配合 Promise 语义来处理。
普通函数只能用 try/catch 捕获同步错误
普通函数中抛出的错误(如 throw new Error())是同步发生的,可以直接被外层 try/catch 捕获:
- 如果函数内部有 await 或 Promise 链,但函数本身不是 async,那 await 语法会报错(语法不允许);
- 若函数返回一个被 reject 的 Promise,它不会自动触发 catch 块——因为 throw 并未发生,只是返回了一个失败的 Promise;
- 调用者必须手动用 .catch() 处理返回的 Promise 错误,无法靠同步 try/catch 覆盖。
async 函数让 try/catch 同时覆盖同步和异步错误
async 函数内部的 try/catch 不仅能捕获 同步 throw,还能捕获 await 表达式所等待的 Promise 被 reject 的情况:
- await someAsyncOp() 若返回被 reject 的 Promise,会像同步 throw 一样中断执行,并跳入最近的 catch 块;
- 这使得错误处理逻辑集中、线性,避免了 .then().catch() 的分散写法;
- 注意:try/catch 只对函数体内 await 有效;如果 async 函数只是 return 一个被 reject 的 Promise(没 await 它),错误不会进入 catch,而是由调用方通过 .catch() 或外层 await 捕获。
调用层面的错误处理方式不同
两者暴露错误的方式决定了调用方如何应对:
- 普通函数:错误只发生在执行时,调用方用 try/catch 即可;若它返回 Promise,则错误需用 .catch() 或 await + 外层 try/catch;
- async 函数:总是返回 Promise,所以调用方要么链式调用 .catch(),要么在另一个 async 函数中用 await 并配 try/catch;
- 漏掉 Promise 错误处理(比如没加 .catch 也没 await)会导致未捕获拒绝(unhandled rejection),可能触发 Node.js 进程警告或浏览器控制台报错。
实际建议
写 async 函数时,推荐按需选择错误处理风格:
- 需要集中处理多种错误(同步计算 + 异步请求),优先在函数内用 try { await xxx } catch (e) { ... };
- 若只是简单转发异步结果,可直接 return Promise,不加 await 和 try/catch,把错误处理权交给调用方;
- 永远不要让 async 函数返回的 Promise “裸奔”——确保它被 await 或 .catch() 显式处理。











