await 后 promise reject 才触发 catch;未 await 的 promise 失败不会进入当前 try-catch,必须显式 await 所有可能失败的异步操作以避免 unhandled rejection。

在 async/await 中,用 try-catch 捕获异常和同步代码几乎一样,但关键在于:只有 await 后面的 Promise 被 reject 时,才会进入 catch;直接 throw 或未 await 的 Promise reject 不会触发当前 try-catch。
try-catch 必须包裹 await 表达式
await 是“暂停点”,也是异常冒泡的捕获点。没 await 的 Promise 失败,不会中断函数执行,也不会被外层 try-catch 捕获。
✅ 正确写法:
async function fetchData() {
try {
const res = await fetch('/api/data'); // await 让错误可被捕获
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
console.error('请求失败:', err.message);
throw err; // 可选择重新抛出
}
}
避免漏掉未 await 的 Promise
常见陷阱:调用多个异步函数但只 await 了部分,其余 Promise 的 reject 会变成未处理拒绝(unhandled rejection)。
⚠️ 错误示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
async function badExample() {
try {
const p1 = Promise.reject('oops'); // 没 await,错误不会进 catch
await Promise.resolve('ok');
} catch (e) {
console.log(e); // 永远不会执行
}
}
✅ 解决方式:
- 所有可能失败的异步操作都显式 await
- 批量并发时,用 Promise.allSettled() 替代 Promise.all(),避免一个失败就全盘崩溃
- 对不关心结果的异步任务(如日志上报),单独加 .catch() 防止 unhandled rejection
多个 await 可共用一个 try-catch
适合有依赖关系的串行异步操作,任一环节失败都会跳到 catch,后续 await 不再执行。
async function uploadFlow() {
try {
const token = await getUploadToken();
const result = await uploadFile(file, token);
await notifySuccess(result.id);
return result;
} catch (err) {
console.error('上传流程中断:', err);
await cleanup(); // 清理资源
throw err;
}
}
需要区分错误类型?在 catch 里判断
可以根据 error 实例类型、属性或 message 做差异化处理:
- 网络错误(TypeError、AbortError)→ 提示重试
- 业务错误(自定义 Error 子类或 code 字段)→ 弹窗提示具体原因
- 4xx/5xx HTTP 错误 → 根据状态码跳转或降级
例如:
catch (err) {
if (err.name === 'AbortError') {
console.log('请求被取消');
} else if (err instanceof ApiError && err.code === 'INVALID_TOKEN') {
redirectToLogin();
} else {
showGenericError();
}
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










