async本身不提速,关键在于释放i/o等待时间实现并发;应并行发起独立请求、避免循环串行await、拆分长任务让出事件循环、缓存重复异步调用结果。

用好 async 本身不直接提速,关键在于它释放了等待 I/O 的时间,让程序能并发处理多个任务。真正提升效率的是配合正确的调度、避免阻塞、减少冗余等待这些实践。
并行发起独立请求,别串行 await
多个互不依赖的异步操作(比如查用户、拉配置、读缓存),如果一个接一个 await,总耗时是它们之和;改用并发模式,总耗时接近最慢那个。
- ❌ 错误写法(串行):
const user = await getUser(id);<br>const config = await getConf();<br>const cache = await getCache(key);
- ✅ 正确写法(并行):
const [user, config, cache] = await Promise.all([<br> getUser(id),<br> getConf(),<br> getCache(key)<br>]);
避免在循环里逐个 await
遍历数组批量调用异步函数时,直接 for...of + await 会变成串行执行,效率极低。
- ⚠️ 危险模式:
for (const id of ids) {<br> await fetchItem(id); // 每次都等上一个结束<br>} - ✅ 推荐方式:
await Promise.all(ids.map(fetchItem)); // 一次性发起全部 - 如需控制并发数量(防压垮服务),可用
p-limit或async-pool等库限流
尽早释放事件循环,拆分长任务
单个 async 函数如果内部逻辑太重(比如处理几千条数据),会持续占用事件循环,导致其他任务延迟响应。
- 对大数组做耗时计算时,可分批次加
await Promise.resolve()让出控制权 - Node.js 中也可用
setImmediate()或process.nextTick()插入微任务断点 - 浏览器环境可用
await new Promise(r => setTimeout(r, 0))实现类似效果
善用缓存与惰性初始化
重复的异步调用(如加载配置、鉴权信息)没必要每次都发请求。用 Promise 缓存结果,后续直接复用。
- 简单缓存示例:
let _confPromise;<br>function getConfig() {<br> if (!_confPromise) {<br> _confPromise = fetch('/api/conf').then(r => r.json());<br> }<br> return _confPromise;<br>} - 更健壮方案可用
AsyncLazy(.NET)或自定义带过期/重试的封装 - 注意内存泄漏:长期存活的缓存应设 TTL 或用
WeakMap管理










