Как запустить параллельные обещания в JS, а затем дождаться их завершения без Promise.all ()? - PullRequest
3 голосов
/ 21 июня 2019

Так что мне нужно сделать что-то вроде:

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

поверх этого идентификатора должен быть реализован async function sleep(N), и через несколько секунд уровень рекурсии будет высоким, что, безусловно, не подходит для оперативной памяти.

Ответы [ 2 ]

5 голосов
/ 21 июня 2019

Соберите все обещания:

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

Тогда вы можете использовать Promise.all на них:

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

Я не могу использовать Promise.all, так как НЕ УХОДУ, ЕСЛИ ОДИН или ВСЕ ИМ НЕ УДАЛСЯ

Конечно, вы можете. Поскольку вы добавляете .catch к каждому обещанию, которое возвращает цепочку обещаний обратно в ветвь разрешения, promise1 никогда не будет отклоняться, поэтому Promise.all также никогда не будет отклонять.

3 голосов
/ 21 июня 2019

Вы можете использовать метод Promise.allSettled:

Метод Promise.allSettled () возвращает обещание, которое разрешается после все данные обещания были либо решены, либо отклонены, с массив объектов, каждый из которых описывает результат каждого обещания.

Поскольку это относительно новый продукт, он может еще не поддерживаться большинством браузеров. Вот такое заполнение:

 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);
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...