async/await 是 Promise 的语法糖,async 函数必返回 Promise 并自动包装返回值,await 只能在 async 函数中使用且仅暂停当前函数,多个独立请求应优先用 Promise.all 并行,错误处理必须用 try/catch 包裹每个 await。

async/await 不是魔法,它只是 Promise 的语法糖——用对了清爽如水,用错了照样掉坑里。
async 函数必须返回 Promise,但你可能没意识到它“自动包装”了返回值
声明一个 async 函数,哪怕里面全是同步代码,调用它也一定返回一个 Promise:
async function getValue() {
return 42;
}
console.log(getValue()); // Promise {: 42}
这意味着:
• 直接调用 getValue() 得到的是 Promise,不是 42;
• 想拿到真实值,必须 await getValue()(在 async 函数内)或 getValue().then(...)(外部);
• 如果函数里 throw 错误,等价于返回 Promise.reject(...),所以一定要配 try/catch。
await 只能用在 async 函数里,且只“暂停当前函数”,不卡主线程
常见错误:在普通函数或事件回调里直接写 await fetch(...) → 报错 SyntaxError: await is only valid in async function。
- ✅ 正确姿势:把逻辑包进
async函数,再调用它 - ❌ 错误姿势:
button.addEventListener('click', () => { const data = await api(); }) - ⚠️ 注意:await 后面如果不是 Promise,JS 会自动用
Promise.resolve(...)包一层,比如await 123是合法的,但毫无异步意义
多个独立请求别傻傻串行 await,用 Promise.all 并行提速
连续写两个 await 就是串行执行,总耗时 ≈ 两请求之和;而它们彼此无关时,完全可并发发起:
// ❌ 串行:慢 const user = await fetchUser(); const posts = await fetchPosts(); // 等 user 完了才发 posts 请求 // ✅ 并行:快 const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
关键点:
• Promise.all 返回的仍是 Promise,所以可以 await;
• 任一失败会导致整个 Promise.all reject,如需容错,可用 Promise.allSettled;
• 别在 forEach 里 await —— 它不会等待,只是“发出去就不管了”,结果不可控。
错误处理不是可选项,try/catch 必须包裹每个 await 表达式
fetch 失败、JSON 解析出错、后端返回 500……这些都会让 await 抛出异常。不捕获?页面白屏或控制台红字静默崩溃。
async function loadData() {
try {
const res = await fetch('/api/profile');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
console.error('加载失败:', err.message);
// 这里可以 fallback 数据、上报错误、提示用户
return null;
}
}
补充提醒:
• 不要用 .catch() 链在 await 后面(语法错误);
• finally 块适合放清理逻辑(如关闭 loading 状态),无论成功失败都执行;
• 在 React/Vue 组件中触发异步操作,还要防组件卸载后更新已销毁 state 的内存泄漏问题。
真正难的从来不是写对 async/await,而是判断哪些该串行、哪些该并行、哪些该降级、哪些该重试——语法只是表,逻辑才是里。









