async函数内必须用try catch包裹await表达式才能捕获异步错误,因async返回promise,外部try catch仅捕获同步错误;事件处理器中需显式处理promise拒绝,避免错误静默丢失。

async函数里直接写try catch根本捕不到错误
因为 async 函数返回的是 Promise,不是同步执行流。你直接在 async 函数体外用 try catch 包它,只会捕获同步阶段的错误(比如语法错误),而 await 后抛出的异常会被 Promise 拒绝,必须通过 Promise 的错误处理机制来接。
正确写法:在 async 函数内部用 try catch 包 await 表达式
这是最常用也最直观的方式——把可能失败的异步操作用 await 调用,并用 try catch 包裹那行 await 语句本身。
-
catch块能拿到被 reject 的 error 对象,和同步错误一样可读取error.message、error.stack - 不要把整个
async函数体都包进try,只包真正需要错误隔离的await调用即可 - 如果多个
await之间有依赖关系(后一个依赖前一个结果),就该串着写;如果彼此独立,可以考虑Promise.allSettled()避免单点失败阻断全部
async function fetchUserData() {
try {
const res = await fetch('/api/user');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
console.error('获取用户失败:', err.message);
return null;
}
}
在事件处理器或顶层调用处,必须用 .catch() 或 await + try catch
HTML 中常见场景是点击按钮触发 async 函数,比如:button onclick="fetchUserData()"。这时候函数被当作普通回调执行,错误不会冒泡到全局 window.onerror,也不会触发 unhandledrejection(除非你没处理 Promise 返回值)。
- 错误写法:
button onclick="fetchUserData()"—— 返回的 Promise 被丢弃,错误静默丢失 - 正确做法一(推荐):在调用处加
await并包try catch,前提是调用方也是async函数 - 正确做法二:显式调用
.catch(),适合非 async 环境,比如传统事件监听器
document.getElementById('loadBtn').addEventListener('click', async () => {
try {
const data = await fetchUserData();
renderUser(data);
} catch (err) {
showError(err.message);
}
});
别忽略 unhandledrejection,它会暴露漏掉的 Promise 错误
如果你忘了处理某个 async 函数的返回值,或者某个 await 外部没包 catch,浏览器会在控制台报 Uncaught (in promise) ...,同时触发 window.addEventListener('unhandledrejection')。
- 这不是“备用 catch”,而是兜底告警机制,不能替代主动错误处理
- 开发时建议加个简单监听,避免错误被吞掉:
window.addEventListener('unhandledrejection', e => console.warn('未处理的 Promise 拒绝:', e.reason)) - 注意:
e.reason就是被 reject 的值,不一定是Error实例,可能是字符串或对象
真正麻烦的不是语法怎么写,而是忘记 await 后没处理、或把 await 写在了条件分支里却只在部分路径加了 catch —— 这类逻辑缺口很难靠工具发现,得靠代码审查和测试覆盖。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











