async 和 await 是基于 Promise 的异步语法糖:async 函数返回 Promise,await 暂停执行直至 Promise 完成;需在 async 函数内使用,配合 try/catch 处理错误,支持自动包装非 Promise 值,但须合理设计串行/并行逻辑。

async 和 await 是什么?
它们是 JavaScript 中处理异步操作的语法糖,本质仍是基于 Promise,但让异步代码写起来像同步代码一样线性、易读。async 用于声明一个函数会返回 Promise,await 只能在 async 函数内部使用,用来“暂停”执行直到右侧的 Promise 被 resolve 或 reject。
怎么用 await 等待 fetch 请求?
直接在 async 函数里用 await fetch(...) 获取响应,再用 await response.json() 解析数据。注意:两次 await 都可能抛错,必须捕获。
async function getUser() {
try {
const response = await fetch('/api/user');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
return data;
} catch (err) {
console.error('获取用户失败:', err.message);
}
}
-
fetch()本身只在网络失败时 reject,HTTP 404/500 不会触发 catch,得手动检查response.ok - 不能在顶层(非函数作用域)直接写
await,否则报错Uncaught SyntaxError: await is only valid in async function - 如果只是想等多个请求并行,别用
await Promise.all([...])套两层,直接await Promise.all([fetch(...), fetch(...)])
为什么 await 后面不是 Promise 也能用?
await 会自动把非 Promise 值包装成已 resolve 的 Promise。比如 await 42 等价于 await Promise.resolve(42),所以能安全地混用同步值和异步逻辑。
- 这让你可以统一用
await处理缓存命中(返回普通对象)和缓存未命中(返回Promise) - 但别滥用:对纯同步值加
await没实际意义,还可能掩盖本该同步执行的逻辑意图 - 类型工具(如 TypeScript)不会自动推导
await 42的类型为number,需显式标注或依赖上下文
常见错误:忘记处理 rejected Promise
没加 try/catch,或只捕获了第一层 await,后续链式调用仍可能出错。尤其在连续 await 多个异步操作时,任一环节 reject 都会导致整个函数中断。
立即学习“Java免费学习笔记(深入)”;
async function badExample() {
const user = await fetchUser(); // 如果这里 reject,下面不会执行
const posts = await fetchPosts(user.id); // 这行根本跑不到
return { user, posts };
}
- 每个
await行为都可能失败,建议按业务粒度包裹try/catch,而不是整个函数包一层 - 避免在循环中无节制
await:比如for (const id of ids) await fetch(`/item/${id}`)是串行,性能差;改用Promise.all(ids.map(id => fetch(...))) -
async函数返回值总是Promise,即使你return 123,调用方也必须用.then()或外层await接收











