使用 Promise.all 避免等待每个单独的循环迭代

Posted

技术标签:

【中文标题】使用 Promise.all 避免等待每个单独的循环迭代【英文标题】:Avoid await for each individual loop iteration with Promise.all 【发布时间】:2020-07-17 14:25:58 【问题描述】:

我想在 for 循环迭代期间更改对象数组 (t) 的项目 (f)。 下面的代码可以正常工作。

for (const f of t) 
  f.value = await getValue(f.a, f.b)
  f.coordinate = 'not empty'


但是,我想在调用 getValue 时避免使用 await 关键字 ,而是使用 Promise.all 或其他替代方法,以便同时执行许多 getValue 函数调用。目前,每次迭代都等待getValue 函数完成,然后再继续下一次循环迭代。

无需更改正在迭代的对象,我将使用promises 数组变量来解决它,我在每次迭代期间将承诺推送到该变量。但是,当我更改迭代对象数组时,我不确定如何实现我的目标。

【问题讨论】:

但这不也一样吗?为什么要避免使用await @fedesc 我想在 for 循环执行后的最后使用 await Promise.all 以等待所有 getValue 调用完成。当前循环等待每个单独的 getValue 调用完成。因此它不会并行运行。至少我认为这是 promise.all 的用例——我不是专家。 所以在你的 for...of 循环中只需要准备迭代器以便稍后在 await Promise.all() 中调用 @fedesc:我不太清楚你的意思。 【参考方案1】:

在您的 for...of 循环中,只需准备稍后在 await Promise.all() 中调用的可迭代对象

let promises = [];
for (const f of t) 
  promises.push(getValue(f.a, f.b))
  f.coordinate = 'not empty'

// and then call Promise all with or without async await syntax
Promise.all(promises).then((values) => 
  console.log(values);
);
// or
let result = await Promise.all(promises);

我不知道你的承诺是如何工作的 (getValue),但我猜它是一个接受变量并返回承诺的函数——但这就是想法, 准备好可迭代对象,然后调用它。

【讨论】:

谢谢,但问题是我想要 f.value 中的数据(getValue 的结果),就像我展示的示例一样。 您必须使用 promise.all 带回所有值,然后再次对其进行迭代以将其放入 f.value 中。这确实使事情复杂化。 for...of with await 非常适合您尝试做的事情。为什么不直接等待呢?

以上是关于使用 Promise.all 避免等待每个单独的循环迭代的主要内容,如果未能解决你的问题,请参考以下文章

Promise.all() 不等待异步进程

async-await 同时触发(等待)多个异步操作

使用 Promise.all 避免唯一错误 E11000

结合像Promise.all这样的等待

在 forEach 之后使用 Promise.all() 渲染 NodeJS 页面之前等待 Firebase 数据加载

Promise.all()函数中的JS“等待仅在异步函数中有效”[重复]