在async函数中控制异步流程的核心是合理使用await、Promise.all/race、try/catch及超时封装;串行用await,独立并行用Promise.all,超时用Promise.race+setTimeout,条件与循环中await合法但需注意语义。

在 async 函数中控制异步流程,核心是合理使用 await、Promise 构造方法(如 Promise.all、Promise.race)、错误处理(try/catch),以及必要时配合 async/await 与回调逻辑的组合。关键不在于“避免 await”,而在于明确每个异步操作的依赖关系和执行意图。
按顺序执行:用 await 串行等待
当后续操作必须等前一个完成(比如先登录再获取用户数据),直接用 await 是最清晰的方式。它让代码像同步一样可读,且天然支持错误冒泡。
- 每个
await表达式会暂停函数执行,直到 Promise settled(fulfilled 或 rejected) - 连续多个
await就是严格串行;中间出错会直接跳进catch - 注意不要无意义地
await已 resolve 的值(如await 42),虽合法但无实际作用
并行执行:用 Promise.all 统一等待多个任务
若几个异步操作彼此独立(比如同时拉取用户信息、订单列表、通知数),应避免逐个 await,改用 Promise.all 并发发起、统一收口。
const [user, orders, notices] = await Promise.all([fetchUser(), fetchOrders(), fetchNotices()]);- 任一 Promise reject,整个
Promise.all就 reject,需用try/catch捕获 - 若需“部分失败也继续”,可用
Promise.allSettled,它总是 resolve,返回每个结果的状态对象
超时控制:封装带 timeout 的 Promise
原生 async/await 不提供超时语法,但可通过 Promise.race + setTimeout 实现请求级超时。
- 写一个辅助函数:
const withTimeout = (promise, ms) => Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), ms))]); - 然后:
const data = await withTimeout(fetch('/api'), 5000); - 注意:超时后原请求仍在后台运行,如有副作用(如发两次请求),需额外考虑取消逻辑(如 AbortController)
条件分支与循环中的异步控制
if/else、for、while 中使用 await 完全合法,但要注意语义是否符合预期。
- 条件判断中:
if (await checkPermission()) { ... }是常见且安全的写法 - for 循环中逐个 await 是串行;想并行,可先生成 Promise 数组再
await Promise.all(promises) - while 循环中 await 同样有效,适合轮询场景,但记得加退出条件和防抖/节流,避免无限请求
不复杂但容易忽略的是:async 函数本身返回 Promise,所以调用它的位置也要用 await 或 .then 处理;控制流程的本质,其实是把异步依赖关系显式表达出来,而不是堆砌语法糖。

















