JavaScript 异步编程终极语法async/await 完全指南基于 Promise用同步写法写异步代码是目前前端 / Node.js 主流标准。一、async/await 是什么async/await 是ES2017 引入的语法糖底层 100% 基于 Promise。它让异步代码写法和阅读都像同步代码但底层依然是非阻塞的。据 2023 State of JS 调查超过90% 开发者在使用 async/await。// 像同步一样优雅的异步代码 async function getUserData(userId) { const response await fetch(/api/users/${userId}) const user await response.json() return user }二、本文你将学到async/await 本质就是 Promiseasync 关键字把函数变成返回 Promise 的函数await暂停执行但不阻塞主线程try/catch 做异步错误处理最舒服的方式串行 vs 并行执行性能关键最常见 5 个坑与避坑async/await 与事件循环、微任务的关系前置知识Promise、事件循环三、三种异步写法对比1. 回调老办法嵌套地狱function getUserPosts(userId, callback) { fetchUser(userId, (err, user) { if (err) return callback(err) fetchPosts(user.id, (err, posts) { if (err) return callback(err) fetchComments(posts[0].id, (err, comments) { callback(null, { user, posts, comments }) }) }) }) }2. Promise 链式好一点但仍有嵌套function getUserPosts(userId) { return fetchUser(userId) .then(user fetchPosts(user.id) .then(posts fetchComments(posts[0].id) .then(comments ({ user, posts, comments })) ) ) }3. async/await现代最清晰async function getUserPosts(userId) { const user await fetchUser(userId) const posts await fetchPosts(user.id) const comments await fetchComments(posts[0].id) return { user, posts, comments } }四、餐厅类比秒懂不用 async/await站在柜台等餐阻塞后面的人用 async/await坐下点单厨房做菜异步你可以玩手机不阻塞做好了服务员端来Promise 决议你继续吃函数恢复执行核心await 看起来在等实际上 JS 主线程完全空闲。五、async 关键字作用只有一个让函数返回 Promise。// 普通函数 function greet() { return Hello } greet() // Hello // async 函数 async function greetAsync() { return Hello } greetAsync() // Promise { fulfilled: Hello }规则return 普通值 → 自动包装Promise.resolve(值)throw 错误 → 自动变成Promise.reject(错误)return Promise → 不会重复包装支持所有函数形式普通函数函数表达式箭头函数对象方法类方法六、await 关键字作用暂停 async 函数直到 Promise 落定然后返回结果。只能在两个地方用 awaitasync 函数内部ES 模块顶层top-level await可以 await 什么任何 Promise最常用thenable 对象普通值会立刻继续但仍进入微任务关键特性await 暂停函数不暂停线程async function test() { console.log(1) await delay(1000) console.log(2) } console.log(A) test() console.log(B) // 输出顺序A → 1 → B → 2底层原理await 会把后面的代码变成微任务等 Promise 决议后再执行。等价于async example() → 等价于 → example().then(...)七、错误处理try/catch/finallyasync/await 最爽的地方用同步的 try/catch 处理异步错误。async function fetchUserData(userId) { try { const res await fetch(/api/users/${userId}) if (!res.ok) throw new Error(HTTP 错误) return await res.json() } catch (err) { console.error(失败, err.message) throw err // 继续向上抛 } finally { // 无论成功失败都执行 hideLoading() } }常见陷阱catch 后不 rethrow → 错误被 “吃掉”函数返回 undefined。八、串行 vs 并行性能分水岭1. 串行慢每个请求等上一个完成。// 总耗时 ≈ 三个请求时间相加 const user await fetchUser(userId) const posts await fetchPosts(userId) const notes await fetchNotes(userId)2. 并行快推荐所有请求同时发送用Promise.all。// 总耗时 ≈ 最慢那个请求 const [user, posts, notes] await Promise.all([ fetchUser(userId), fetchPosts(userId), fetchNotes(userId) ])选择规则串行下一步依赖上一步结果并行互相独立追求速度九、Promise 组合方法和 await 天生一对Promise.all全部成功才成功任一失败立即失败Promise.allSettled全部完成不管成败Promise.race谁先完成谁赢成功失败都算Promise.any谁先成功谁赢Promise.withResolvers外部控制 resolve/rejectPromise.try统一捕获同步 / 异步错误十、最常见 5 个错误必考1. 忘记写 await拿到 Promise 对象不是结果。const res fetch(/api) // ❌ 是 Promise const data await res.json() // ❌ 崩溃2. forEach await 无效forEach 不会等待异步函数。✅ 替换为for...of或Promise.all3. 无脑串行本该并行慢 210 倍。4. 没有错误处理未捕获的 Promise 拒绝会崩溃应用。5. try 里 return 但没 await错误抓不到// ❌ 错 try { return fetch(...) } catch {}// ✅ 对 try { return await fetch(...) } catch {}十一、Top-level awaitES 模块在模块最外层直接使用 await无需 async 函数。// config.js const config await fetch(/config.json).then(r r.json()) export default config适用场景加载配置动态导入数据库连接初始化特性检测十二、高级模式1. 指数退避重试async function fetchWithRetry(url, retries 3) { for (let i 0; i retries; i) { try { return await fetch(url) } catch (e) { if (i retries - 1) throw e await delay(1000 * 2 ** i) } } }2. 超时控制async function withTimeout(promise, ms) { return Promise.race([ promise, new Promise((_, reject) setTimeout(() reject(new Error(超时)), ms) ) ]) }3. 取消请求AbortController4. 异步迭代器 for await...of十三、核心总结async/await Promise 的语法糖async 函数一定返回 Promiseawait暂停函数不阻塞线程await 后面的代码是微任务错误处理用try/catch并行用Promise.all性能提升巨大是目前工业界标准异步写法 概念 汇总1. 核心概念async/await同类Promise 语法糖、协程、线性异步、generator yieldasync function同类Promise 包装函数、异步函数、隐式返回 Promiseawait同类暂停执行、等待 Promise、微任务调度2. 执行与调度微任务Microtask同类Promise 回调、await 后续代码、优先级高于宏任务非阻塞暂停同类协程、挂起、异步让出线程Top-level await同类模块异步初始化、动态导入、配置等待3. 错误处理async try/catch同类同步风格错误捕获、Promise.catch ()、错误冒泡错误被吃掉同类未 rethrow、隐式 resolve、隐形 BUG4. 并发模式串行异步同类依赖执行、顺序请求、瀑布式请求并行异步同类并发请求、Promise.all、同时执行指数退避重试同类容错、重试机制、抖动避免超时控制同类Promise.race、熔断、请求保护5. 相关 APIPromise.all同类并行等待、全部成功Promise.allSettled同类容忍失败、批量结果Promise.race同类竞速、优先返回Promise.any同类优先成功、多源备用AbortController同类异步取消、终止请求、清理机制Async Iterator同类异步流、for await...of、流式读取6. 反模式 / 陷阱Missing await同类Promise 对象误用、undefined 崩溃、类型错误forEach async同类并发失控、不等待、执行顺序混乱Return without await in try同类错误逃逸、catch 不生效、隐性 bugUnhandled Rejection同类未捕获异常、程序崩溃、控制台警告