如何在JS中运行并发承诺,然后在没有Promise.all()的情况下等待它们完成?

时间:2019-06-21 12:05:25

标签: javascript node.js promise

所以我需要做类似的事情:

promiseFunction1().then((result) => {

}).catch((err) => {
    // handle err
});

promiseFunction2().then((result) => {

}).catch((err) => {
    // handle err
});

....

promiseFunctionN().then((result) => {

}).catch((err) => {
    // handle err
});

// WAIT FOR BOTH PROMISES TO FINISH
functionWhenAllPromisesFinished();

我无法使用Promise.all,因为如果其中任何一个或全部失败,我都不会在意。我需要确保所有诺言都已完成。另外,then()中的回调函数对于每个promiseFunctionX()来说都是非常独特的。

我确定这有些琐碎,但我无法弄清楚。我最初的想法是在运行承诺的上限中保留一个计数器,并在运行承诺时将其递增,并在finally()中将其递减。然后,我需要一些async function checkIfRunningPromisesAre0(),但是我也不知道如何实现它,因为它看起来像递归地狱。

这是我的示例,但认为这只是嘲笑执行不佳的一种材料:

async function RunningPromisesFinished(){
    if(RunningPromises > 0){
        await sleep(2000);
        return await RunningPromisesFinished();
    }else{
        return true;
    }
}

最重要的是,该ID必须实现async function sleep(N),并且在几秒钟内递归级别将很高,这肯定对RAM不利。

2 个答案:

答案 0 :(得分:5)

遵守所有承诺:

  const promise1 = promiseFunction1().then((result) => {
   }).catch((err) => {
     // handle err
   });

然后您可以在它们上使用Promise.all

  await Promise.all([promise1, promise2, /*...*/ ]);
  

我无法使用Promise.all,因为如果其中任何一个或全部失败,我都不会在意

肯定可以。当您向每个承诺中添加一个.catch并将承诺链返回到解决方案分支时,promise1将永远不会拒绝,因此Promise.all也永远不会拒绝。

答案 1 :(得分:3)

您可以使用Promise.allSettled方法:

  

Promise.allSettled()方法返回一个承诺,该承诺将在   所有给定的承诺都已解决或被拒绝,   每个对象描述每个承诺的结果的数组。

由于这是相对较新的内容,因此大多数浏览器可能尚不支持。这是一个polyfill:

 function allSettled(promises) {
    let wrappedPromises = promises.map(p => 
      Promise.resolve(p)
        .then(
           val => ({ state: 'fulfilled', value: val }),
           err => ({ state: 'rejected', reason: err })
        )
    );
    return Promise.all(wrappedPromises);
 }