async函数异常处理取决于await位置、返回值类型及错误抛出时机;await后必须为promise,否则异常无法被捕获;正确写法需在try内await异步操作并处理响应错误;调用方须显式处理返回的promise;应按业务语义选择细粒度或粗粒度容错策略。

async 函数内部逻辑直接决定异常能否被正确捕获、在哪一层暴露、以及是否意外丢失。它不是“加了 try/catch 就安全”,而是每一步执行顺序、await 位置、返回值类型和错误抛出时机,都在影响异常流的走向。
await 后必须是 Promise,否则异常捕获失效
await 的作用是“等待一个 Promise settled”,并把它的 rejection 自动转为同步可 catch 的错误。但如果 await 后面跟的是普通值(如字符串、对象)、未返回 Promise 的函数,或漏写了 await,那这行代码就变成同步执行,错误不会触发 Promise 拒绝机制,try/catch 也就无从捕获。
- ❌ 错误写法:
const res = fetch('/api')—— 没有 await,Promise 被丢弃,失败即 unhandled rejection - ❌ 错误写法:
await doSomethingSync()—— 若doSomethingSync不返回 Promise,await 不起异步作用,内部抛错虽能 catch,但已脱离异步错误语义 - ✅ 正确写法:
const res = await fetch('/api'),且后续res.ok判断、res.json()都在 try 块内
错误真正发生的环节常在 await 之后,而非 fetch 调用瞬间
网络请求失败(如超时、CORS、DNS 失败)会让 fetch() 返回的 Promise 直接 reject,这时 await 会立即 throw;但更多业务级错误出现在响应处理阶段:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
if (!res.ok) throw new Error(`HTTP ${res.status}`)—— 手动拒绝,需在 try 内 -
await res.json()—— 若后端返回空响应、HTML 页面或非法 JSON,会抛SyntaxError -
await res.text()后再JSON.parse()—— 同样可能 SyntaxError,也得包在 try 中
async 函数返回值语义决定调用方如何接住错误
async 函数无论 return 还是 throw,最终都映射为 Promise 的 fulfilled 或 rejected 状态。这意味着:
- 函数内
throw new Error('xxx')→ 返回的 Promise 是 rejected - 函数内
return { data: 123 }→ 等价于Promise.resolve({ data: 123 }) - 调用方若只写
fetchUser()而不处理返回值(比如放在 onclick 里),Promise 拒绝就会静默丢失 - 必须显式处理:要么用
await+try/catch,要么链式.catch(),或全局监听unhandledrejection
细粒度容错比粗粒度兜底更体现逻辑严谨性
不是所有错误都该让整个流程中断。根据业务语义选择捕获层级:
- 获取用户头像失败 → 单独 try/catch,降级为默认头像,不影响主流程
- 支付接口调用 → 强依赖,任一环节失败应终止后续,并统一记录订单异常,适合外层集中 catch
- 多个并行请求(如拉取用户、权限、配置)→ 用
Promise.allSettled(),避免单个失败导致全链路中断
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










