JavaScript 异步函数中 try catch 怎样处理 Promise 拒绝

作者:袖梨 2026-07-11
try...catch仅能捕获await的Promise拒绝,无法捕获未await的Promise拒绝;fetch需手动检查res.ok并throw才能触发catch;并行请求推荐用Promise.allSettled避免错误传播。

在 JavaScript 异步函数中,try...catch 只能捕获同步错误和 await 表达式中被拒绝的 Promise,不能直接捕获未 await 的 Promise 拒绝(比如忘记 await 的 fetch() 调用)。关键在于:只有被 await 的 Promise 拒绝时,才会抛出异常并进入 catch 块。

✅ 正确用法:await + try catch 捕获 Promise 拒绝

当使用 await 等待一个 Promise 时,若该 Promise 被拒绝(reject),JavaScript 会将其转化为一个同步抛出的异常,try...catch 就能捕获它。

  • 确保对所有可能失败的异步操作都加 await
  • catch 块接收到的是 reject 的 reason(通常是 Error 实例或任意值)
  • 多个 await 可共用一个 try catch,但要注意错误定位
示例:
async function fetchData() {  try {    const res = await fetch('/api/data'); // 如果网络失败或 4xx/5xx,fetch 不 reject,但 .json() 可能 fail    if (!res.ok) throw new Error(`HTTP ${res.status}`);    const data = await res.json(); // 这里可能因 JSON 解析失败而 reject    return data;  } catch (err) {    console.error('请求或解析失败:', err.message);    throw err; // 可选择重新抛出,让调用方处理  }}

❌ 常见错误:漏掉 await,导致 Promise 拒绝未被捕获

如果写了 fetch('/api/data') 却没加 await,这个 Promise 就变成“未处理的拒绝”(unhandled rejection),try...catch 完全无效,控制台会报 warning,且可能触发全局 unhandledrejection 事件。

  • 错误写法:fetch('/api/data').then(...) 在 try 内部 —— then 的错误需在内部用 .catch() 处理
  • 混用 await.then() 容易遗漏错误分支
  • 推荐统一用 async/await 风格,避免嵌套回调式错误处理

⚠️ 注意:fetch 默认不 reject HTTP 错误状态

fetch 只在网络故障或请求被阻止时 reject;404、500 等响应仍返回 resolve 的 Response 对象。必须手动检查 res.okres.status 并主动 throw 才能进入 catch

立即学习“Java免费学习笔记(深入)”;

  • 不要依赖 fetch 自动抛错
  • 常见做法:await fetch → 检查 res.ok → await res.json() → catch 统一处理

? 补充技巧:并行请求的错误隔离

多个异步操作并行时(如 Promise.all),任一 Promise 拒绝会导致整个 Promise.all 拒绝。如需各自独立处理,可用 Promise.allSettled 或包装每个 Promise:

  • await Promise.all([p1, p2]):一个失败,全部失败
  • await Promise.allSettled([p1, p2]):返回每个结果的状态(fulfilled/rejected),不会抛异常
  • 或封装成 async () => { try { ... } catch(e) { return { error: e } } }

相关文章

精彩推荐