async函数内异常边界由await位置和try-catch包裹范围共同决定,错误必须发生在被try包裹的await执行过程中才能被捕获;外部或整个函数体包裹无效,未处理的Promise拒绝将触发unhandledrejection。

async 函数内的异常边界,不是由函数声明本身划定的,而是由 await 表达式的位置 和 try-catch 的包裹范围 共同决定的。它不等同于同步代码中“函数体即作用域”的直觉,关键在于:错误必须发生在被 try 包裹的 await 执行过程中,才能被捕获。
异常只在 await 处“落地”,不是在 async 函数开头就生效
async 函数返回 Promise,自身不会同步抛错;真正触发错误处理的,是 await 等待的那个 Promise 被 reject,或 await 后续操作(如 res.json())同步抛出异常。也就是说:
- await fetch('/api/user') 本身通常不报错(除非网络完全不可达等极少数情况)
- 但 await fetch(...) 后紧接着 if (!res.ok) throw new Error() 就会进入 catch
- await res.json() 如果后端返回空字符串或 HTML,会直接 SyntaxError,也落入 catch
try-catch 必须紧贴 await,不能只包调用层
把整个 async 函数用 try-catch 包起来没用——因为函数立即返回 Promise,错误发生在 Promise resolve/reject 之后,不在 try 块执行期间。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- ❌ 错误写法:外部调用时 try-catch ——
try { fetchUser() } catch(e) {...}捕不到任何网络错误 - ✅ 正确写法:内部 await 前后加 try-catch ——
try { const res = await fetch(...); ... } - ⚠️ 注意:多个 await 可共用一个 try 块,但第一个出错就会跳到 catch,后续 await 不再执行
未捕获的 Promise reject 会变成 unhandled rejection
如果某个 await 没被 try-catch 包住,又没接 .catch(),Promise 拒绝就会漏掉,触发全局 unhandledrejection 事件。
立即学习“Java免费学习笔记(深入)”;
- 浏览器控制台会警告,可能影响稳定性监控
- 建议加全局兜底:
window.addEventListener('unhandledrejection', e => { e.preventDefault(); logError(e.reason); }) - 但兜底不能替代业务层精准处理,比如用户提示、重试逻辑仍需在 await 附近实现
错误边界不等于 UI 层的 React 错误边界
JS 层的 async 异常边界纯属执行流控制,和 React 的 ErrorBoundary 是两回事:
- 前者解决“请求失败怎么响应”,属于数据获取层
- 后者解决“子组件 render 崩溃怎么不白屏”,属于 UI 渲染层
- 两者可以配合:async 请求失败 → setState 触发 UI 更新 → ErrorBoundary 不介入;但若请求成功后渲染组件时出错,ErrorBoundary 才起作用

















