You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何并行运行两个for await循环?

解决方案:让多个for await...of循环并行运行

你碰到的问题很典型:for await...of串行执行的——它会从头到尾跑完第一个异步迭代器的所有迭代(这里是无限的),才会轮到第二个循环。要让它们并行运行,你需要把每个循环放到独立的异步任务里,然后同时启动这些任务。

下面是几种可行的方案:

方法1:用Promise.all并行执行异步处理函数

最直接的方式是把每个for await循环包装成独立的async函数,然后用Promise.all同时启动它们:

// 把第一个循环的逻辑封装成异步函数
async function handleSignal() {
  try {
    for await (const thing of signal()) {
      // 你的业务逻辑,比如处理thing
      console.log('处理signal的thing:', thing);
    }
  } catch (err) {
    console.error('signal处理出错:', err);
    // 在这里添加错误处理,比如日志记录或恢复逻辑
  }
}

// 封装第二个循环的逻辑
async function handleAnotherSignal() {
  try {
    for await (const thing of anotherSignal()) {
      // 第二个循环的业务逻辑
      console.log('处理anotherSignal的thing:', thing);
    }
  } catch (err) {
    console.error('anotherSignal处理出错:', err);
  }
}

// 并行启动两个处理任务
await Promise.all([handleSignal(), handleAnotherSignal()]);

关键说明:

  • Promise.all会立刻触发两个异步函数的执行,它们各自的for await循环会在独立的异步流里运行,不会互相阻塞。
  • 每个函数里的try/catch很重要:如果某个迭代器抛出错误,这个try/catch会捕获它,不会影响另一个任务的运行(如果用Promise.all,默认一个任务reject会导致整个all reject,但我们在内部捕获了错误,所以另一个任务会继续)。

方法2:用Promise.allSettled(适用于需要等待所有任务结束的场景)

如果你希望不管某个任务是否失败,都等待所有任务完成,可以用Promise.allSettled替代Promise.all

await Promise.allSettled([handleSignal(), handleAnotherSignal()]);
// 这里会等到两个任务都完成(不管成功或失败)才继续执行后续代码

为什么原代码不行?

原代码的执行顺序是:

  1. 进入第一个for await...of循环,不断从signal()异步迭代器取值处理
  2. 只有当第一个循环完全结束(但你的是无限循环,永远不会结束),才会执行第二个循环

而把循环封装到独立async函数后,两个循环的异步迭代会同时被调度,事件循环会在两个迭代器的可用值之间切换,实现并行处理。


内容的提问来源于stack exchange,提问作者Siddharth Shyniben

火山引擎 最新活动