Как перебрать массив в javascript, с обещаниями внутри блока цикла и дождаться завершения всех обещаний, чтобы продолжить - PullRequest
0 голосов
/ 03 октября 2018

Мне нужно перебрать массив в javascript с некоторыми значениями, которые будут использоваться для вызова асинхронной функции, которая возвращает обещание.Я не могу продолжить следующий раздел кода без выполнения всех обещаний.

В следующем примере функция "processInvoices" должна разрешать обещание до тех пор, пока все обещания внутри не будут выполнены (предположим, что "verifyInvoice" являетсяасинхронная функция с разным временем отклика):

processInvoices(invoices)
{
  return new promise(resolve=>
    {
        invoices.forEach(number=> 
            {

                confirmInvoice(number)
                    .then(result=>{
                              if (!result)
                                {resolve(false);}
                    });
            });
        resolve(true);  // Resolving here doesn´t mean that all promises where completed!

    });
}

init()  // triggered at load..
{
    let invoices = [2,4,8,16,31];
    processInvoices(invoices)
        .then(result=>
            { 
                if (result) // It´s probable that the following message isn´t accurate:
                    console.log('All invoices were processed');
            });

}

С приведенным выше кодом я не могу быть уверен, что "console.log (или любая подпрограмма)" будет выполнен сразу после того, как все обещания былизавершено.

1 Ответ

0 голосов
/ 03 октября 2018

forEach работает синхронно .Если вы хотите дождаться разрешения всех Обещаний до полного разрешения processInvoices, вместо этого следует использовать Promise.all;map каждый номер счета к Promise и вызов Promise.all в результирующем массиве Обещаний.Кроме того, ваш

if (!result) {resolve(false);}

звучит так, как будто это попытка обработать ошибку, если результата нет - в этом случае вам следует отклонить Promise вместо вызова resolve.В идеале неудачный вызов confirmInvoice приведет к отклонению Promise, но если это не то, что вы можете исправить, выведите ошибку, если result неверно, поэтому вы можете обработать ее в catch в init.Например:

function processInvoices(invoices) {
  return Promise.all(
    invoices.map(number => (
      confirmInvoice(number)
        .then(result => {
          // This will result in the `Promise.all` rejecting:
          if (!result) throw new Error('Failed to confirm invoice ' + number);
        })
    ))
  );
}
function init() {
  const invoices = [2, 4, 8, 16, 31];
  processInvoices(invoices)
    .then(result => {
        console.log('All invoices were processed');
    })
    .catch((err) => {
      console.log('err: ' + err);
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...