Javascript 如何为承诺数组的数组做 promise.all?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36094865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:37:20  来源:igfitidea点击:

How to do promise.all for array of array of promises?

javascriptnode.jspromise

提问by Rohit Vyavahare

I am trying to run array of functions parallel and when everybody finishes I want work on that result. I am using promises. Now, I can put all functions in an array and can do Promise.all(array of functions) But I have array like

我正在尝试并行运行函数数组,当每个人都完成时,我想要处理该结果。我正在使用承诺。现在,我可以将所有函数放在一个数组中,并且可以执行 Promise.all(array of functions) 但我有类似的数组

[[promise1, promise2], [promise3,promise4], [promise5,promise6]],

where each promise is promisified function. Promise reference document says parameter in Promise.all should be an iterable object and my array is iterable. But it is not working for me. I think It is executing [promise1, promise2] as a promise but not individual promise.

每个promise都是promisified函数。Promise 参考文档说 Promise.all 中的参数应该是一个可迭代对象,而我的数组是可迭代的。但它对我不起作用。我认为它正在执行 [promise1, promise2] 作为承诺而不是个人承诺。

Can anybody please help me how I can achieve it or is there any better way ?

任何人都可以帮助我如何实现它或者有什么更好的方法吗?

回答by Matías Fidemraizer

You need to also call Promise.allfor each array item:

您还需要Promise.all为每个数组项调用:

const promise4all = Promise.all(
   promiseArray.map(function(innerPromiseArray) {
        return Promise.all(innerPromiseArray);
   })
);

Or directly:

或者直接:

// Fix: Promise.all.bind is required because it seems like Promise.all
// implementation relies on "this"
const promise4All = Promise.all(promiseArray.map(Promise.all.bind(Promise)))
// or
// const promise4All = Promise.all(promiseArray.map(p => Promise.all(p)))

This way the outer Promise.allgets the grouped promises in other Promise.all:

通过这种方式,外部Promise.all获得了 other 中的分组承诺Promise.all

promise4all.then(function(promiseGroupResult) {
  // promiseGroupResult is the actual result of each promise group
  // and you'll be able to get each result this way: promiseGroupResult.somePropertyName
});

回答by Bergi

You can just use Promise.allon all inner arrays, then on the outer array, to get a promise for the array of arrays:

您可以只Promise.all在所有内部数组上使用,然后在外部数组上使用,以获得对数组数组的承诺:

Promise.all(promiseArrArr.map(Promise.all, Promise)).then(arrArr => …)

Notice that Promise.alltakes an array of promises, not an array of promise-returning functions.

请注意,它Promise.all接受一组承诺,而不是一组承诺返回函数。

回答by k06a

If you have fixed number of subarrays, I'd suggest to use this simple solution:

如果您有固定数量的子数组,我建议使用这个简单的解决方案:

const balancePromises = [...];
const symbolPromises = [...];

const [balances, symbols] = await Promise.all([
    Promise.all(balancePromises),
    Promise.all(symbolPromises)
]);

Several promises could also be parallelized like this:

几个 promise 也可以像这样并行化:

const [
    balances,
    debt,
    name,
] = await Promise.all([
    this.contract.getBalanceOf(user),
    this.contract.getDebtOf(user),
    this.contract.getNameOf(user),
]);

回答by jfriend00

One other option is to flatten your array of arrays into a single array that you can then use Promise.all()on directly. Straight from an example on MDN, you can do that like this using .reduce()and .concat():

另一种选择是将您的阵列阵列展平为一个您可以Promise.all()直接使用的阵列。直接从MDN 上示例中,您可以使用.reduce()and这样做.concat()

var promises = [[promise1, promise2], [promise3,promise4], [promise5,promise6]];

Promise.all(promises.reduce(function(a, b) { return a.concat(b); }, []))
  .then(function(results) {
    // all done here
    // results are in a flattened array
});

This solution allows the original promises array to contain either individual promises or arrays of promises or any combination of the two. It's flexible in that way and it provides the results in a single flattened array of results that are in the same order as the original promises, but are flattened into a single array. Because Promise.all()requires that you pass it an array, the other solutions presented here require the input to be a strict array of arrays - that array cannot have any plain promises in it only arrays of promises. This solution is more flexible in that way and will accept either type of input.

此解决方案允许原始承诺数组包含单个承诺或承诺数组或两者的任意组合。它在这方面很灵活,它以单个扁平化的结果数组提供结果,这些结果与原始承诺的顺序相同,但被扁平化到单个数组中。因为Promise.all()要求您向它传递一个数组,所以这里介绍的其他解决方案要求输入是一个严格的数组数组 - 该数组不能有任何简单的承诺,只有承诺数组。这种解决方案在这方面更加灵活,并且可以接受任何一种类型的输入。

For example, this will work just fine if the input happens to be like this:

例如,如果输入恰好是这样的,这将工作得很好:

var promises = [promise1, promise2, [promise3, promise4], [promise5, promise6]];

See working demo: https://jsfiddle.net/jfriend00/dLsktyyn/

查看工作演示:https: //jsfiddle.net/jfriend00/dLsktyyn/



Or you might find it useful to have the flatten()function lying around for other uses:

或者您可能会发现将该flatten()函数用于其他用途很有用:

function flatten(arr) {
    return arr.reduce(function(a, b) { return a.concat(b); }, []);
}

var promises = [[promise1, promise2], [promise3,promise4], [promise5,promise6]];

Promise.all(flatten(promises)).then(function(results) {
    // all done here
});    

回答by jhtong

If you are looking to flatten the multi-array, and pend on all promises, you can now do:

如果您希望展平多数组,并等待所有承诺,您现在可以执行以下操作:

const promiseAll = Promise.all(promiseArray.flat());

回答by Dmitriy

You can use this approach:

您可以使用这种方法:

var promisesArray = [
    [promise1, promise2],
    [promise3,promise4],
    [promise5,promise6]
].reduce(function (arr, item) {
    item.forEach(function (promise) {
       arr.push(promise);
    });
    return arr;
}, []);
Promise.all(promisesArray).then(function () {
    // code
});