如何并行调用多个 async 函数

并行执行多个 async 函数用 Promise.all([fn1(), fn2()]),所有任务同时启动、等待全部完成,结果按传入顺序返回。允许部分失败用 Promise.allSettled,只要第一个结果用 Promise.race/any。

最佳实践
Node.js 事件循环与异步任务示意

用 Promise.all:把多个 async 函数的调用(注意是调用,返回 Promise 的数组)放进去,它们就会同时启动,await 等到全部完成后拿到结果数组。 关键点是先调用、再统一等待——如果写成逐个 await,就变成串行了。

基本用法

async function main() {
  // 错误:串行,总耗时 1s + 1.5s
  // const r1 = await fetchUser();
  // const r2 = await fetchOrders();

  // 正确:并行,总耗时 ≈ 1.5s(最慢的那个)
  const [user, orders] = await Promise.all([fetchUser(), fetchOrders()]);
}

注意:fetchUser() 和 fetchOrders() 在传入 Promise.all 的那一刻就已经开始执行了,Promise.all 只是负责"收集结果"。

四种 Promise 组合器

方法 行为
Promise.all 全部成功才成功;一个失败立即整体 reject
Promise.allSettled 等全部结束,成败都收,结果带 status 字段
Promise.race 谁先有结果(无论成败)就返回谁
Promise.any 第一个成功的结果;全失败才 reject
// 部分失败也能拿到其余结果
const results = await Promise.allSettled(tasks);
const ok = results.filter(r => r.status === 'fulfilled').map(r => r.value);

对数组元素并行

const results = await Promise.all(ids.map(id => fetchById(id)));

常见问题(FAQ)

Q:并行会超限打挂下游接口吗?

会。数组很长时 map + Promise.all 瞬间发出全部请求。用 p-limit 限制并发数,或分批 Promise.all。

Q:Promise.all 中一个失败,其他 Promise 会取消吗?

不会取消(Promise 本身不可取消),它们仍在后台跑完,只是 Promise.all 提前 reject。需要真正取消要配合 AbortController。

Q:async 函数不 await 就调用会怎样?

立即开始执行并返回 Promise。这既是并行的基础,也是"忘记 await 导致错误吞掉"的常见 bug 来源——要么 await,要么显式 .catch()。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台