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

Roh*_*are 19 javascript node.js promise

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

[[promise1, promise2], [promise3,promise4], [promise5,promise6]],
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*zer 25

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

const promise4all = Promise.all(
   promiseArray.map(function(innerPromiseArray) {
        return Promise.all(innerPromiseArray);
   })
);
Run Code Online (Sandbox Code Playgroud)

或直接:

// 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)))
Run Code Online (Sandbox Code Playgroud)

这样外部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
});
Run Code Online (Sandbox Code Playgroud)

  • 很高兴知道为什么我得到了反对票。好吧,所有答案都被否决了。就我而言,我已经提供了一个答案来处理 OP 解释的场景。如果以这种方式嵌套 promise 是否是一个好的设计,这不是问题。 (3认同)

k06*_*06a 9

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

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

const [balances, symbols] = await Promise.all([
    Promise.all(balancePromises),
    Promise.all(symbolPromises)
]);
Run Code Online (Sandbox Code Playgroud)

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

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


Ber*_*rgi 8

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

Promise.all(promiseArrArr.map(Promise.all, Promise)).then(arrArr => …)
Run Code Online (Sandbox Code Playgroud)

请注意,它Promise.all接受一个promises数组,而不是一个promise-returns函数数组.


jfr*_*d00 6

另一种选择是将阵列数组展平为单个阵列,然后可以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
});
Run Code Online (Sandbox Code Playgroud)

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

例如,如果输入恰好像这样,这将很好用:

var promises = [promise1, promise2, [promise3, promise4], [promise5, promise6]];
Run Code Online (Sandbox Code Playgroud)

查看工作演示: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
});    
Run Code Online (Sandbox Code Playgroud)


jht*_*ong 6

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

const promiseAll = Promise.all(promiseArray.flat());
Run Code Online (Sandbox Code Playgroud)