等待多个for-each语句完成

时间:2019-03-26 18:17:40

标签: javascript arrays asynchronous foreach

我有一个集群数组,其中每个集群都包含一组功能。我使用两个forEach语句来遍历群集和功能,以便将每个功能存储在“结果”数组中。

我需要进一步处理“结果”数组。但是,当我要求数组的长度时,它说的是长度为0,尽管我可以在控制台中看到其中包含功能。我需要找到一种方法,仅在forEach循环完成时才处理“结果”数组。

我已经了解到此问题是由JavaScript中的异步数据处理引起的。我已经尝试注册Promise,但是我无法使其工作,因为在示例中始终使用一个forEach循环,但是彼此之间有两个forEach循环。

这是我的代码:

var result = [];

clusters.forEach((cluster) => {
  getFeatures(cluster_id, (features) => {
  features.forEach((feature) => {
    result.push(feature);
  });
  });
});

//do something with result array
console.log("resulting features array length: " + result.length); //results in 0

2 个答案:

答案 0 :(得分:1)

您实际上不需要内部的forEach,因为只需将要素复制到可以用.push(...stuff)完成的结果中,就必须保证getFeatures才能调用{{1 }}兑现所有诺言,等待它们全部完成:

Promise.all

如果您需要按顺序排列结果,则可以用它们解决承诺,然后将结果展平:

const result = [];

const allDone = Promise.all(clusters.map((cluster) => new Promise(resolve => {
  getFeatures(cluster_id, (features) => {
    result.push(...features);
    resolve();
  });
})));

allDone.then(() => {
  // result is ready to use here
});

答案 1 :(得分:0)

您可以将结果转换为Promise,然后将解析的数组放平:

Promise.all(clusters.map(cluster => new Promise(resolve => 
    getFeatures(cluster.id, resolve)
  ))
)
// as .flat() doesn't work in Node.js <= 10, this is a workaround:
//.then(clusterFeatures => clusterFeatures.reduce((acc,curr) => [...acc, ...curr], []))
.then(clusterFeatures => clusterFeatures.flat())
.then(features => ... );