async/await本质是用同步写法表达异步逻辑,其核心在于函数内部暂停执行但不阻塞主线程,依赖微任务队列调度,await仅等待Promise状态变化并交还结果,而非线程阻塞。

掌握 async/await 不是背几个关键字就行,关键在于理解它如何改变代码执行节奏、错误流向和并发控制方式。系统学,得按“认知—实践—排错—优化”四步走,每一步都紧扣真实开发中的卡点。
先建立正确心智模型:async/await 不是“让异步变同步”,而是“用同步写法表达异步逻辑”
很多初学者误以为加了 await 就能阻塞整个线程,结果发现 console.log 顺序不对、变量没等到值就用了——根源是没理清“函数内部暂停”和“主线程继续运行”的关系。
- async 函数一调用就立即返回一个 Promise,内部代码被放进微任务队列,不阻塞后续同步代码
- await 只暂停当前 async 函数的执行,不是暂停 JS 引擎;它等的是 Promise 状态变化,然后把 resolved 值“交还”给下一行
- await 后面可以跟任何值:Promise 自动等待;普通值(如数字、字符串)直接返回,不触发异步流程
动手写三类典型场景,别只看示例
光读文档不如亲手改错。建议按顺序写并调试以下三个小任务,每个都暴露一类常见问题:
- 串行依赖链:先获取用户 ID,再查订单列表,最后取第一条订单详情。重点练 await 怎么自然承接上一步结果,避免在 then 里套 await
- 并行无依赖请求:同时发三个接口(用户、配置、公告),用 Promise.all 包一层 async/await,对比单独 await 的耗时差异
- 条件分支 + 异步判断:比如“如果用户已登录,加载个人数据;否则跳转登录页”。注意 try/catch 不能覆盖 if 分支里的 await,错误要提前兜住
必须跨过的三道坎:错误处理、并发控制、超时机制
项目里 80% 的 async/await 问题集中在这三块,教程常一笔带过,但实际天天碰到:
- 错误不能只靠 try/catch:await 后的 Promise 被 reject,会直接抛出异常;但网络超时、接口 500、JSON 解析失败,需要分层捕获——fetch 后手动检查 response.ok,再 await response.json()
- 并发数失控:循环里直接 await 每次请求,等于串行;想并发又怕打崩后端?用 Promise.allSettled 或加信号量(如 p-limit 库)控流
- 没有超时 = 不可控:await 一个没设 timeout 的 fetch,页面可能白屏几秒。封装一个 timeout 函数,用 Promise.race 包住 fetch 和 setTimeout
进阶习惯:从“能跑通”到“可维护”
熟练不是写得快,是改得稳、查得准、接得住别人留下的 async 代码:
- 函数职责单一:一个 async 函数只做一件事(如 loadUser),不要混 UI 更新、日志、错误上报逻辑
- 显式标注异步边界:在调用处加注释说明“此处 await 可能延迟渲染”,方便协作和性能分析
- 善用 DevTools 的 Async Stack Trace:Chrome 调试时勾选 “Async” 选项,能看清 await 是在哪一层挂起、哪一层恢复的


















