本文详解为何 await 后 promise 被拒绝时代码仍继续执行,并提供规范的错误捕获方案——必须用 try...catch 包裹 await 表达式,否则拒绝将变为未处理的 promise rejection,导致后续逻辑意外运行且触发全局警告。
本文详解为何 await 后 promise 被拒绝时代码仍继续执行,并提供规范的错误捕获方案——必须用 try...catch 包裹 await 表达式,否则拒绝将变为未处理的 promise rejection,导致后续逻辑意外运行且触发全局警告。
在使用 async/await 时,一个常见误区是认为只要 await 了一个被拒绝(rejected)的 Promise,函数就会立即中断、跳过后续语句。但事实并非如此:await 本身不会自动捕获异常;它只是将 Promise 的拒绝状态“抛出”为一个可被 try...catch 捕获的 JavaScript 异常。若未显式捕获,该异常会向上传播,但当前 async 函数体内的同步代码(如 console.log)并不会被跳过——因为 await 的执行流程并未被阻断,而是因缺少错误处理机制,导致拒绝未被响应。
来看原始代码的问题根源:
async function f1() {
const p = await f2(); // ❌ f2() 返回一个 rejected Promise,但此处无 catch
console.log("This line should not get printed since the promise was rejected");
}
async function f2() {
Promise.reject("promise rejected"); // ⚠️ 忘记 return!此行创建了 rejected Promise,但未返回,f2 实际返回的是 undefined(fulfilled)
}
⚠️ 注意:上述 f2 还存在一个隐蔽错误——Promise.reject(...) 被调用但未 return,因此 f2() 实际返回的是 undefined(即一个已兑现的 Promise),而非被拒绝的 Promise。这会导致 await f2() 不抛异常,console.log 正常执行。真正触发拒绝需改为:
async function f2() {
return Promise.reject("promise rejected"); // ✅ 显式 return rejected Promise
}
但即使修复了 return,若 f1 中仍无 try...catch,运行时将抛出 Uncaught (in promise) "promise rejected",且 console.log 依然执行——因为异常未被捕获,JS 引擎不会回滚已解析的语句位置。
✅ 正确写法必须包含错误边界:
async function f1() {
try {
const p = await f2(); // ✅ await 在 try 内,拒绝会被捕获
console.log("This line should not get printed since the promise was rejected");
} catch (error) {
console.error("Caught rejection:", error); // 输出: "Caught rejection: promise rejected"
// 此处可做降级处理、上报或静默忽略
}
}
async function f2() {
return Promise.reject("promise rejected");
}
f1();
? 关键要点总结:
- await 不是“自动 try-catch”,它仅将 Promise rejection 转换为可抛异常;
- 所有 await 表达式都应置于 try...catch 块中,尤其当其结果影响后续逻辑时;
- 忘记 return Promise 是高频低级错误,建议启用 ESLint 规则(如 require-await 和 no-return-await 配合检查);
- 在生产环境,未捕获的 Promise rejection 会触发 unhandledrejection 事件,应全局监听并告警:
window.addEventListener('unhandledrejection', event => { console.warn('Unhandled rejection:', event.reason); event.preventDefault(); // 阻止默认控制台警告(按需) });
遵循以上实践,才能确保异步错误可控、流程健壮,避免“看似报错却继续执行”的陷阱。










