Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何为承诺数组执行promise.all?_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 如何为承诺数组执行promise.all?

Javascript 如何为承诺数组执行promise.all?,javascript,node.js,promise,Javascript,Node.js,Promise,我正在尝试并行运行函数数组,当每个人都完成时,我希望对结果进行处理。 我在使用承诺。现在,我可以把所有函数放在一个数组中 Promise.all(函数数组) 但是我有一个数组 [[promise1, promise2], [promise3,promise4], [promise5,promise6]], 其中每个承诺都是承诺的功能。 Promise参考文档说Promise.all中的参数应该是iterable对象,我的数组是iterable。 但这对我不起作用。我认为这是将[允诺人1,允诺人

我正在尝试并行运行函数数组,当每个人都完成时,我希望对结果进行处理。 我在使用承诺。现在,我可以把所有函数放在一个数组中 Promise.all(函数数组) 但是我有一个数组

[[promise1, promise2], [promise3,promise4], [promise5,promise6]],
其中每个承诺都是承诺的功能。 Promise参考文档说Promise.all中的参数应该是iterable对象,我的数组是iterable。 但这对我不起作用。我认为这是将[允诺人1,允诺人2]作为一种承诺而不是个人的承诺来执行


有谁能帮我实现这一目标,或者有更好的方法吗?

您还需要致电
Promise。每个数组项的所有

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

您可以使用以下方法:

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

您只需在所有内部阵列上使用
Promise.all
,然后在外部阵列上使用,即可获得阵列阵列的承诺:

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

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

另一个选项是将数组展平为单个数组,然后可以直接使用
Promise.all()
。直接从一开始,您可以使用
.reduce()
.concat()
这样做:

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

例如,如果输入恰好如下所示,这将很好地工作:

var promises = [promise1, promise2, [promise3, promise4], [promise5, promise6]];
const [
    balances,
    debt,
    name,
] = await Promise.all([
    this.contract.getBalanceOf(user),
    this.contract.getDebtOf(user),
    this.contract.getNameOf(user),
]);
请参阅工作演示:


或者,您可能会发现将
flant()
函数用于其他用途非常有用:

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

如果您有固定数量的子阵列,我建议使用以下简单解决方案:

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

const [balances, symbols] = await Promise.all([
    Promise.all(balancePromises),
    Promise.all(symbolPromises)
]);
几个承诺也可以像这样并行:

var promises = [promise1, promise2, [promise3, promise4], [promise5, promise6]];
const [
    balances,
    debt,
    name,
] = await Promise.all([
    this.contract.getBalanceOf(user),
    this.contract.getDebtOf(user),
    this.contract.getNameOf(user),
]);

如果您希望扁平化多阵列,并等待所有承诺,现在可以执行以下操作:

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

你需要这样做,你只需要一个简单的承诺数组,正如它所要求的那样。无论谁对所有答案进行了规范性的否决,请评论它们的错误。
promise.all
接受一个承诺对象数组,它是根据你已经调用的函数的返回值创建的。“现在,我可以将所有函数放在一个数组中,并且可以做承诺。all(array of functions)”不会调用函数,并且会使用输入数组的重构副本解析返回的承诺。如果知道我为什么会得到否决票,那将是一件好事。嗯,所有答案都被否决了。在我的例子中,我已经提供了一个答案来处理OP解释的场景。如果嵌套承诺这种方式是否是一个好的设计,这不是问题所在。顺便说一句,没有理由做
Array。从(参数)
,承诺只实现一个值。@Bergi我在“直接”调用时修复了它我总是得到结果
Promise.all在非对象上调用
,但是第一个代码片段起作用了,谢谢。@Matíasfidemrazer简写符号const promise4All=Promise.all(promiseArray.map(Promise.all)),没有抛出一个错误,Promise.all在非对象上调用。嗯,这种方法的缺点是,传递给
then
处理程序的值的结构(值的平面数组)不再与输入结构(承诺数组的数组)同构,因此很难匹配哪个承诺产生了哪个值。从这个意义上说,@Bergi的方法似乎更好。@torazaburo-这取决于你想对结果做什么。结果与这种方法完全一致,所以你不会不知道哪个与哪个相匹配,它们可能更容易在平面阵列中导航。这是另一个选项,取决于您想要什么。添加了有关此解决方案如何在承诺数组或承诺数组或两者的任意组合/混合上工作的信息,并以与原始承诺相同的顺序在单个平坦的结果数组中提供输出。是否有“忽略”的方法返回数组中某些项的结果?我需要清空一个数据库表,然后继续用新内容填充它,但我想将记录创建查询的结果存储在变量中。我能在一个
承诺中实现这一切吗?这绝对是最优雅的解决方案,在我看来也是最好的答案。我仍然很难理解.map(Promise.all,Promise)是如何工作的,但它确实工作了,而且很漂亮。@ian它将
Promise
传递为,以提供
this
值。这与
.map(Promise.all.bind(Promise))
@Bergi非常感谢您花时间回复我,我花了几个小时试图研究将此绑定到Promise,但我仍然不知道将“this”绑定到“Promise”如何允许Promise.all将承诺返回到“outer”答应我。all@IanH只是
Promise.all
是一个方法,因此如果作为回调传递,则需要绑定到
Promise
。你也可以编写
promiseArr.all(promiseArr.map(promiseArr=>promiseArr.all(promiseArr))
同意,这是迄今为止最好的解决方案。此解决方案的优点在于,它保持了返回承诺的数组深度,而不像其他答案那样将其压平。起初,这个解决方案本身让我有点难以理解,但一旦我理解了,它就变得如此明显。非常感谢!这很有效