我有一个集群数组,其中每个集群都包含一组功能。我使用两个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
答案 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 => ... );