如何做承诺.all for array of promises.

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

本文关键字:array of promises for all 何做 承诺      更新时间:2023-09-26

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

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

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

任何人都可以帮助我如何实现它还是有更好的方法?

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

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

或直接:

// 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)))

这样,外部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
});

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

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

请注意,Promise.all 采用 promise 数组,而不是 promise 返回函数数组。

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

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

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

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

如果你有嵌套的承诺数组 - 试试这个:

const nestedResults = await Promise.all(
    nestedPromises.map(promises => Promise.all(promises))
);
另一种

选择是将数组数组展平为单个数组,然后可以直接使用Promise.all()数组。 直接从 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
});

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

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

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

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

<小时 />

或者,您可能会发现将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
});    
<小时 />

编辑

或者,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());

您可以使用此方法:

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
});
这是我

的片段。

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

这是结果。

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