async/await 是 Promise 的语法封装,不改变异步本质但简化回调与错误处理;async 函数自动返回 Promise,await 暂停执行而不阻塞线程,需在 async 内使用,配合 try/catch 可清晰捕获 rejection。

async/await 不是新语法糖,而是 Promise 的语法封装,它本身不改变异步行为,但能显著降低回调嵌套和错误处理的复杂度。
async 函数必须显式返回 Promise
声明为 async function 的函数,无论内部是否用 await,返回值都会被自动包装成 Promise。直接 return 42 等价于 return Promise.resolve(42);抛出错误等价于 return Promise.reject(err)。
常见错误:在 async 函数里忘记 await 调用另一个 async 函数,导致返回的是 pending Promise 而非实际值。
- ✅ 正确写法:
const data = await fetchUser(); - ❌ 错误写法:
const data = fetchUser(); // data 是 Promise,不是用户对象 - ⚠️ 注意:
await只在async函数内有效,顶层 await 仅在模块作用域(ESM)或 REPL 中可用
await 会暂停执行但不阻塞线程
await 后面的表达式必须是 thenable(通常是 Promise),它会让 JS 引擎暂停当前 async 函数的执行,把控制权交还给事件循环,等 Promise settle 后再继续。这和同步阻塞完全不同。
立即学习“Java免费学习笔记(深入)”;
使用场景:串行请求、依赖前序结果的逻辑、需要按顺序处理多个异步操作。
- 多个
await是串行的:await a(); await b();表示 b 等 a 完成后再开始 - 想并发执行?用
Promise.all([a(), b()]),再await它 - 性能影响:过度串行化会拉长总耗时;盲目并发可能压垮接口或触发限流
try/catch 比 .catch() 更自然地捕获异常
await 后的 Promise 被 reject,会以异常形式抛出,可直接用 try/catch 捕获——这比链式调用中每个 .then() 后都接 .catch() 清晰得多。
容易踩的坑:只在最外层 try/catch,却忽略中间某个 await 实际上没被包裹。
- ✅ 推荐:
async function load() { try { const user = await fetch('/user'); const posts = await fetch(`/posts?uid=${user.id}`); return { user, posts }; } catch (err) { console.error('加载失败:', err.message); } } - ❌ 危险:
await fetch('/user').catch(handleErr);—— 这样后续await fetch(...)仍可能抛未捕获异常 - ⚠️ 注意:
catch捕获的是 Promise rejection,不是同步 throw;若需区分网络错误、解析错误等,得靠检查err.name或响应状态码
真正难的从来不是写 async/await,而是判断哪些操作该串行、哪些该并发、哪些该降级,以及如何让错误提示对用户有意义——语法只是工具,决策才决定质量。











