如何并行调用多个 async 函数

并行执行多个 async 函数用 Promise.all([fn1(), fn2()]),函数调用先开始执行,Promise.all 在全部成功后按输入顺序返回结果,任一拒绝则提前拒绝。收集所有成败用 Promise.allSettled;race 取首次完成,any 取首次成功。

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

用 Promise.all:把多个 async 函数的调用(注意是调用,返回 Promise 的数组)放进去,函数调用会先开始执行,Promise.all 汇总其结果,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()]);
}

这里的并发主要让 I/O 等待重叠,不会让同一线程上的 CPU 密集计算自动并行。

注意: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。需要取消时,可向支持 AbortSignal 的底层操作传递信号并主动 abort;这不能撤销已完成的副作用。

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

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

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台