await 不捕获异常,promise reject 会立即抛出;需用 try/catch 捕获,或谨慎使用 .catch() 转换,避免混用 .then().catch() 与 await。

await 本身不捕获异常,它只是把 Promise 的状态“等出来”;真正决定异常是否抛出的,是 Promise 的 reject 被谁处理、何时处理。
await 不会自动吞掉 reject
当 await 后面的 Promise 被 reject,JavaScript 引擎会立即把 rejection 值当作运行时异常抛出,就像 throw 一样。这意味着:如果没有 try/catch 捕获,错误会向上传递,可能终止当前 async 函数,甚至导致 unhandledrejection。
- async 函数内部没写 try/catch → 错误冒泡到调用者,或触发全局 unhandledrejection
- await 后跟的是已 reject 的 Promise(比如 Promise.reject(404))→ 立即抛出,不会等后续代码
- await 后跟的是未 catch 的异步操作(如 fetch 失败但没检查 response.ok)→ 也可能间接引发 reject
try/catch 是最直接的捕获方式
在 await 表达式周围加 try/catch,是最常见也最明确的错误处理手段。它能捕获 Promise reject 的值,也能捕获 await 过程中同步抛出的错误(比如解析响应体时 JSON.parse 报错)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- catch 块接收到的参数,就是 Promise reject 的 reason(可以是 Error 实例、字符串、数字等)
- 一个 try 可以包裹多个 await,一次 catch 覆盖所有可能失败点,但要注意错误来源是否清晰
- 避免空 catch 或仅 console.log,应根据业务决定重试、降级、提示用户还是继续抛出
Promise.catch 也能拦截,但和 await 配合要小心
你可以在 await 前就对 Promise 调用 .catch(),提前消费 reject,让 await 等到一个“总是 fulfilled”的 Promise。但这会改变错误传播路径,需谨慎使用。
- Promise.reject(‘fail’).catch(e => e) → await 得到 ‘fail’,不会抛异常
- 适合做兜底转换(如把网络错误转成默认数据),但会掩盖原始错误类型和堆栈
- 如果 .catch() 返回一个新 reject 的 Promise,await 仍会抛出 —— reject 没被真正处理
不要依赖 .then().catch() 和 await 混用
写成 await promise.then(...).catch(...) 容易误判错误归属:.catch() 捕获的是 then 回调里的错误,不是 promise 本身的 reject。这会让逻辑变复杂且难以调试。
- 推荐统一风格:要么全用 try/catch + await,要么纯链式 Promise(不用 await)
- 混用时注意 .catch() 返回值:若返回非 Promise 值,await 得到该值;若返回 rejected Promise,await 仍会抛出
- 尤其警惕在 .then() 里手动 throw —— 这会创建新的 rejection,和原 Promise 的 reject 无关
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










