如何制作Promise.all的多个并行子承诺?

时间:2018-01-22 22:56:12

标签: javascript node.js

我有一个数组,对于它的每个元素,我进行一个返回Promise的异步调用。在履行时,那些Promise会发出多个独立请求,这些请求也会导致Promise s。我想制作一个等待所有孩子Promise.all()的{​​{1}}超级Promise。我已经有了为初始Promise生成Promise.all()数组的代码。

Scheme

2 个答案:

答案 0 :(得分:0)

不,你不能这样做。您只能在已有的一系列承诺上调用Promise.all。但是,您可以通过多级Promise.all

为每一组儿童承诺作出承诺
return Promise.all(elements.map(element =>
    doWorkWith(element).then(childResults =>
        Promise.all(childResults.map(doWorkOnChildren))
    )
));

这里的关键元素是从父Promise.all()处理程序返回子.then()(这里通过胖箭头函数隐式完成),因此它被链接到更高级别的承诺,因此在所有子承诺也得到解决之前,不会解决更高级别Promise.all()

您将获得一系列结果数组的承诺。如果你认为合适,请将它展平。

答案 1 :(得分:0)

可能有许多解决方案取决于具体情况。以下代码可以假设您的所有低级请求都是可执行函数,并且每次执行都返回Promise。

const highLevelRequests = [requests1, requests2, ..., requestsN];
const requests1 = [request1_1, request1_2, ..., request1_N];
const requests2 = [request2_1, request2_2, ..., request2_N];
// ...
const requestsN = [requestN_1, requestN_2, ..., requestN_N];

const superPromise = Promise.all(
  highLevelRequests.reduce((acc, request) =>
    [...acc, ...request.map(request => request())]
  , [])
);

superPromise.then(superResult => {
  // process superResult
});

最后,我们得到一个包含Promise.all的详细承诺列表,因此我们只需在.then()上致电superPromise

关于given code

更新。这不是一个单一的承诺列表方法,我只是以更严格的方式重复你的逻辑。

var items = [2, 4, 8];
console.log(items + " starting array");
var fn = function (N) {
  return new Promise(resolve => setTimeout(() => resolve(N * 2), ((Math.floor((Math.random()) * 5) + 1) * 1000)));
};

Promise.all(items.map(fn))
.then(data => {
  console.log(data + " L1 super promise");
  return Promise.all(
    data.reduce((acc, i) => 
      [...acc, ...[1, 2, 3, 4].map(x => fn(x * i))]
    , []));
})
.then((final) => {
  console.log(final + " L2 super promise");
  return final;
})