async/await是Promise的语法糖,错误常因执行流中断、错误静默丢失或Promise状态误用导致;须在async函数内使用await,配合try/catch捕获异常,对无关异步操作应分离容错,且仅对真正Promise值使用await。

async/await 本身是 Promise 的语法糖,写错不报语法错误,但一运行就崩——问题往往藏在“看起来像同步、实则异步”的逻辑断点里。排查重点不是找拼写,而是盯住执行流是否被意外中断、错误是否静默丢失、Promise 状态是否被误用。
不能在非 async 函数里用 await
这是最典型的语法限制:await 只能在用 async 声明的函数内部使用。
- ❌ 错误写法:
await fetch('/api/user'); - ✅ 正确写法:
async function getUser() {
const res = await fetch('/api/user');
return res.json();
} - ⚠️ 注意:顶层 await 在部分环境(如 ES 模块、现代 Node.js)已支持,但浏览器脚本或 CommonJS 中仍不合法,需确认运行上下文。
忘记 try/catch 导致错误未捕获
await 后面的 Promise 一旦 reject,若没被 try/catch 包裹,就会变成未处理的 rejection,控制台报错、后续代码停摆。
- ❌ 危险写法:
async mounted() {
const res = await fetch('/api/data');
this.data = await res.json(); // fetch 失败时直接崩溃
} - ✅ 推荐写法:
async mounted() {
try {
const res = await fetch('/api/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
this.data = await res.json();
} catch (err) {
console.error('加载失败', err);
this.error = err.message;
}
}
多个 await 串行却没做独立容错
如果几个请求彼此无关(比如拉用户信息 + 拉推荐列表),一个失败不该拖垮另一个。全塞进一个 try/catch 会“连坐”。
- ❌ 一刀切写法:
try {
const user = await fetchUser();
const list = await fetchList(); // user 失败,list 根本不执行
} catch (e) { ... } - ✅ 分离容错写法:
const [userErr, user] = await to(fetchUser());
const [listErr, list] = await to(fetchList());
if (userErr) console.warn('用户加载失败', userErr);
if (listErr) console.warn('列表加载失败', listErr);
(to 是轻量工具函数,返回[error, result]元组,避免层层 try/catch)
await 了不返回 Promise 的值
await 期望右侧是一个 Promise 或 thenable。如果 await 了一个普通值(比如数字、字符串、undefined),它不会报错,但会立即 resolve,容易掩盖真实意图。
- ❌ 易混淆写法:
async function test() {
const x = await 'hello'; // 不报错,但 x === 'hello',且无异步行为
return x.toUpperCase();
} - ✅ 检查依据:
只对真正异步操作使用 await;若不确定,加个console.log(x.constructor.name)看是不是 Promise。 - ? 提示:ESLint 插件
no-await-in-loop和require-await可辅助识别可疑用法。


















