在 async 函数中,try-catch 只能捕获被 await 的 Promise 拒绝异常;未 await 的异步调用抛出的异常不会进入 try-catch,而是变为未处理的 Promise rejection,需确保所有可能失败的异步操作都使用 await。

在 async 函数中,try-catch 不能直接捕获 await 后抛出的异常,除非你显式地把 await 放在 try 块内。这是因为 await 会暂停函数执行,但异常仍沿 Promise 链传播,只有被 await 的 Promise 被拒绝时,才触发 catch。
必须 await 才能被 try-catch 捕获
async 函数内部的 Promise 拒绝不会自动进入外部 try-catch,除非你用 await 等待它。直接调用一个返回 Promise 的函数(不 await)相当于“放任不管”,异常会变成未处理的 Promise rejection。
- ✅ 正确:用
await包裹可能失败的异步操作 - ❌ 错误:只调用 async 函数但不 await,异常无法被捕获
例如:
async function fetchData() {
throw new Error('API failed');
}
async function main() {
try {
await fetchData(); // ✅ 必须 await,否则 catch 不生效
} catch (err) {
console.error(err.message); // 输出:API failed
}
}
避免忘记 await 导致静默失败
常见错误是调用 async 函数却漏掉 await,导致异常被忽略,控制台可能只显示 “Uncaught (in promise)” 警告,但 try-catch 完全无效。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
- 检查所有异步调用是否都加了
await - 启用 ESLint 规则
require-await或no-void(配合Promise检查)辅助识别 - 开发时打开浏览器 DevTools 的 “Pause on caught exceptions” 和 “Pause on uncaught exceptions” 有助于定位
多个 await 可共用一个 try-catch
一个 try 块可以包裹多个 await 表达式,只要其中任意一个 Promise 被拒绝,就会跳转到 catch。
async function handleUser() {
try {
const user = await fetchUser();
const profile = await fetchProfile(user.id);
const posts = await fetchPosts(user.id);
return { user, profile, posts };
} catch (err) {
console.error('Failed at:', err.stack);
throw err; // 可选择重新抛出,供上层处理
}
}
慎用 .catch() 替代 try-catch
虽然可以在 await promise.catch(...) 中处理错误,但这会让错误处理逻辑分散、难以维护,也不利于统一异常分类或日志记录。
- 推荐统一用
try-catch+await,语义清晰、堆栈完整 - 避免
promise.then().catch()在 async 函数中混用,易引发控制流混乱 - 若需降级处理(如 fallback 请求),可在
catch内重新 await 其他 Promise

















