简体   繁体   English

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

[英]How to do promise.all for array of array of promises?

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. Promise 参考文档说 Promise.all 中的参数应该是一个可迭代对象,而我的数组是可迭代的。 But it is not working for me.但它对我不起作用。 I think It is executing [promise1, promise2] as a promise but not individual promise.我认为它正在执行 [promise1, promise2] 作为承诺而不是个人承诺。

Can anybody please help me how I can achieve it or is there any better way ?任何人都可以帮助我如何实现它或者有什么更好的方法吗?

You need to also call Promise.all for 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.all gets the grouped promises in other Promise.all :通过这种方式,外部Promise.all获得了其他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
});

You can just use Promise.all on 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.all takes an array of promises, not an array of promise-returning functions.请注意, Promise.all接受一组承诺,而不是一组承诺返回函数。

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),
]);

One other option is to flatten your array of arrays into a single array that you can then use Promise.all() on directly.另一种选择是将您的数组数组展平为一个数组,然后您可以直接使用Promise.all() Straight from an example on MDN , you can do that like this using .reduce() and .concat() :直从上MDN例如,你可以使用是这样做的.reduce().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.因为Promise.all()要求你向它传递一个数组,这里介绍的其他解决方案要求输入是一个严格的数组数组 - 该数组不能有任何简单的承诺,只有承诺数组。 This solution is more flexible in that way and will accept either type of input.这种解决方案在这方面更加灵活,并且可以接受任何一种类型的输入。

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
});    

Edit编辑

Or, Javascript arrays now have .flat() which will flatten the array one level for you:或者,Javascript 数组现在具有.flat() ,它将为您将数组展平一级:

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

Promise.all(promises.flat()).then(function(results) {
    // all done here
    // results are in a flattened array
});

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

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

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
});

Here is my snippet.这是我的片段。

const a = Promise.resolve(1);
const b = Promise.resolve(2);
const c = Promise.resolve(3);
const d = Promise.resolve(4);

const e = Promise.all([a, b]);
const f = Promise.all([c, d]);

Promise.all([e, f])
    .then(res => console.log(res));

And here is the result.这是结果。

[[1, 2], [3, 4]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM