Я просматривал документацию MDN для async await и обнаружил, что есть альтернатива обещанию. Итак, если кофе, чай и описание - три обещания, мы можем ждать их всех let values ​​= ...

2
goxarad784 3 Мар 2021 в 18:40

1 ответ

Лучший ответ

Этот фрагмент:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

Инициализирует каждое обещание только после завершения последнего.

  • Инициализировать первое обещание
  • Подождите, пока он закончится (3 секунды)
  • Инициализировать второе обещание (... и т. Д.)

Напротив, этот фрагмент:

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

Инициализирует все обещания сразу. Тогда это будет

  • дождитесь разрешения первого обещания
  • подождите, пока второе обещание разрешится
  • подождите, пока третье обещание разрешится

Но второй фрагмент имеет серьезный недостаток: если одно из обещаний отклоняется, это может привести к необработанному отклонению, несмотря на то, что перед ним стоит await. Это может произойти, если, например, timeoutPromise1 еще не решен, а timeoutPromise2 отклоняет:

window.addEventListener('unhandledrejection', () => {
  console.error('Unhandled rejection :(');
});

async function timeTest() {
  const timeoutPromise1 = new Promise(resolve => setTimeout(resolve, 5000));
  const timeoutPromise2 = new Promise((resolve, reject) => setTimeout(reject, 500));
  
  await timeoutPromise1;
  await timeoutPromise2;
}

timeTest()
  .catch((error) => {
    console.log('Error caught');
  });

Эта проблема возникает из-за того, что обещание должно быть await редактировано или .catch привязано к нему в точке, в которой оно отклоняет . Если он отклоняет до подключения к нему .catch или await, результатом будет необработанный отказ.

Необработанные отказы, как и необработанные ошибки, уродливы, и их следует избегать. В Node необработанные отклонения не просто плохи , они также устарели и могут полностью привести к сбою процесса Node.

Итак, использование Promise.all - лучший подход, чем ваш второй фрагмент.

5
CertainPerformance 3 Мар 2021 в 15:47