核心在于用.catch()捕获promise链错误或try/catch包裹await,因同步try/catch无法拦截异步reject;.catch放链末统一收口,await需在try内确保异常不被吞掉,未捕获rejection将触发unhandledrejection事件。

JavaScript 中捕获异步操作的异常,核心在于不让错误被吞掉,并确保控制流能按预期转向错误处理分支。同步 try/catch 对 Promise 和 async/await 的异步逻辑无效,必须配合异步语义的错误处理机制。
Promise 链中用 .catch() 捕获异常
Promise 实例一旦 reject,会沿链向后寻找第一个 .catch() 或带第二个参数的 .then(null, handler)。未被捕获的 rejection 会触发全局 unhandledrejection 事件(但不应依赖它兜底)。
- 推荐统一用
.catch()放在链末尾,避免遗漏中间环节错误 - 多个异步步骤串联时,一个环节出错会跳过后续
.then(),直接进.catch() - 示例:
fetch('/api/data')
.then(res => { if (!res.ok) throw new Error('HTTP error'); return res.json(); })
.then(data => console.log(data))
.catch(err => console.error('请求失败:', err.message));
async/await 中用 try/catch 包裹 await 表达式
async 函数内部可以使用同步风格的 try/catch,但仅对 await 后的 Promise rejection 生效;普通同步错误(如语法错误、throw 字面量)也能捕获。
- 每个可能失败的
await调用建议包裹在 try/catch 内,或集中处理整个逻辑块 - 注意:await 后面如果不是 Promise,会自动包装成 resolved Promise,不会进 catch
- 示例:
async function loadData() {
try {
const res = await fetch('/api/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
return data;
} catch (err) {
console.error('加载失败:', err);
throw err; // 可选择重新抛出供上层处理
}
}
并行异步操作需区分 全成功 与 容错执行
多个 Promise 并发时,Promise.all() 遇任一 rejection 就立即 reject;而 Promise.allSettled() 等待全部完成,返回每个结果的状态对象,适合需要汇总成败的场景。
- 用
Promise.all()表示“全都要成功”,失败即中断流程 - 用
Promise.allSettled()表示“都试一遍”,再根据各结果状态做分支处理 - 示例(容错批量请求):
const results = await Promise.allSettled([
fetch('/api/a'),
fetch('/api/b'),
fetch('/api/c')
]);
results.forEach((r, i) => {
if (r.status === 'fulfilled') console.log(`第${i+1}个成功`);
else console.warn(`第${i+1}个失败:`, r.reason);
});
避免常见陷阱:未处理的 rejection 和静默失败
忘记加 .catch() 或 try/catch,或在回调里抛出同步错误但没被 await 捕获,都会导致错误丢失。现代浏览器和 Node.js 会发出警告,但生产环境可能难以察觉。
- 启用 ESLint 规则如
promise/catch-or-return和promise/no-unused-rejections - 在顶层(如事件处理器、setTimeout 回调)中,手动加 .catch() 或 try/catch
- Node.js 中可监听
process.on('unhandledRejection', ...)做日志记录(仅用于监控,不能替代主动捕获)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











