try...catch 能捕获 async 函数内的同步错误和 await 触发的异步拒绝,但必须对每个可能失败的 await 显式使用 try...catch 或 .catch(),否则会触发未处理的 promise 拒绝。

在 JavaScript 中,try...catch 不能直接捕获 async 函数内部的异步错误(比如 await 后 Promise 拒绝),除非你正确地将 await 放在 try 块内。同步错误(如语法错误、运行时抛出的 throw)可以被正常捕获,但异步错误需要显式等待并处理拒绝状态。
同步错误:直接 throw 就能被 try 捕获
async 函数体内的同步代码(不涉及 await)出错时,try...catch 可以立即捕获:
async function demo() {
throw new Error('这是同步错误'); // ✅ 能被外层 try 捕获
}
try {
await demo();
} catch (e) {
console.log(e.message); // 输出:这是同步错误
}
异步错误:必须 await + try 才能捕获
Promise 拒绝(如 fetch 失败、await Promise.reject())不会自动抛出到外层 try,必须用 await 触发其 rejection,再由 try...catch 捕获:
- ❌ 错误写法:没 await,Promise 拒绝被忽略或变成未处理 rejection
- ✅ 正确写法:对每个可能失败的
await表达式加try...catch
async function fetchUser() {
const res = await fetch('/api/user'); // 如果网络失败,res 未定义?不,fetch 本身一般不会 reject,但 .json() 会
return res.json(); // ✅ 这里可能 throw(如返回非 JSON)
}
try {
const user = await fetchUser(); // await 触发整个函数的 rejection 链
} catch (e) {
console.error('获取用户失败:', e.message);
}
多个 await 的错误处理策略
如果一个 async 函数里有多个异步操作,你可以选择:
- 为每个
await单独包裹try...catch(适合差异化处理) - 统一用一个
try...catch包裹所有await(适合统一兜底) - 用
.catch()链式处理单个 Promise(不推荐混用,易丢失上下文)
async function handleMultiple() {
try {
const data1 = await step1();
const data2 = await step2(data1);
const data3 = await step3(data2);
return { data1, data2, data3 };
} catch (e) {
console.error('任一步骤失败:', e);
throw e; // 或返回默认值、重试逻辑等
}
}
避免未处理的 Promise rejection
忘记 await 或漏写 catch 会导致 UnhandledPromiseRejection。建议:
- 所有
await都放在try内,或确保有.catch() - 开发时开启浏览器或 Node.js 的 rejection 监听(
process.on('unhandledRejection', ...)) - 使用 ESLint 插件(如
eslint-plugin-promise)检查遗漏的 catch
关键是记住:async 函数返回 Promise,而 try...catch 只捕获同步抛出或 await 触发的 rejection。没 await,就等于没“接入”错误流。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











