await 外层用 try...catch 可捕获 Promise reject 错误,但前提是 await 的表达式必须返回 Promise;若为普通值、null 或 undefined,则立即返回且不触发 catch。

直接在 await 外层用 try...catch 就能捕获 Promise 被 reject 时的错误,前提是 await 的表达式确实返回一个会 reject 的 Promise。
确保 await 的目标是 Promise
await 只对 Promise 有“等待并解包”的效果;如果 await 的不是 Promise(比如普通值、undefined),它会立即返回该值,不会进入异步流程,自然也不会触发 reject。常见误写:
- 忘记函数实际返回的是普通值而非 Promise(如漏写
return fetch(...)) - 调用了一个没加
async的函数,它内部虽有异步操作但未返回 Promise - await 了 null 或 undefined,此时不会报错,但也不会进入 catch
try...catch 必须包裹 await 表达式本身
错误必须发生在 await 执行期间(即 Promise settle 后被 reject),且 catch 块需紧邻其作用域。例如:
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
async function loadData() {
try {
const res = await fetch('/api/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
console.error('请求失败:', err.message);
throw err; // 或返回默认值
}
}
❌ 错误写法(catch 不生效):
// 把 await 放在 try 外面 → 错失捕获时机
const res = await fetch('/api/data'); // 这里出错就直接冒泡,不进下面的 try
try {
return await res.json();
} catch (e) { ... }
多个 await 可共用一个 try...catch,也可分开处理
根据错误恢复策略决定粒度:
- 想让某一步失败不影响后续步骤 → 单独包每个 await
- 希望整个流程原子性(任一失败就中止)→ 共用一个 try...catch
- 部分步骤需降级处理(如 fallback 请求)→ 在对应 await 外加独立 try...catch
例如:先尝试主接口,失败后自动切到备用接口:
async function getData() {
try {
return await fetch('/api/main').then(r => r.json());
} catch {
try {
return await fetch('/api/backup').then(r => r.json());
} catch (err) {
throw new Error('主备接口均不可用');
}
}
}
注意未被捕获的 Promise rejection 警告
即使你用了 try...catch,如果 Promise 在 await 之前就被 reject(比如 fetch 本身抛同步异常,或构造 Promise 时立即 throw),仍可能触发 Uncaught (in promise) 警告。可靠做法是:
- 确保所有异步源头都正确返回 Promise(如
fetch总是返回 Promise) - 避免在 Promise 构造器中抛同步错误(应改用
Promise.reject()) - 必要时监听全局 unhandledrejection 事件做兜底日志(仅用于监控,不替代业务 catch)

















