Как поймать отклоненное обещание в новом узле выражения v14.4.0 "for await ... of"

Я эмулировал 3 обещания - два разрешенных, одно отклоненное, завернутое в функцию try-catch, но я все еще получаю предупреждения в консоли: (node: 4159) UnhandledPromiseRejectionWarning: необработанное отклонение обещания.

    const emulate = (id, ms) =>
      new Promise((resolve, reject) => {
        if (ms > 1500) reject(id);
        setTimeout(() => {
          resolve(id);
        }, ms);
      });

    const promises = [
      emulate(1, 500),
      emulate(2, 1000),
      emulate(3, 2000)
    ];

    async function stepByStepResolve() {
      try {
        for await (const promise of promises)
          console.log(promise);
      } catch (e) {
        console.log('Err:', e);
      }
    }

    stepByStepResolve();

1 ответ

Когда ты звонишь emulate(3, 2000) в promisesarray, обещание создается и будет отклонено на следующей фазе цикла событий, за исключением случаев, когда вы слушаете его и обрабатываете до этого. Теперь вfor loop, вы слушаете все 3 обещания по порядку, а поскольку emulate(3, 2000) прослушивается последним, он уже был бы отклонен к тому времени, когда вы его выполняете.

Я могу предложить два решения этого:

Решение 1. Просто разместитеemulate(3, 2000) как первый элемент в массиве

let promises = [
  emulate(3, 2000),
  emulate(1, 500),
  emulate(2, 1000),
];

Это позволит его прослушать и поймать до того, как он будет отклонен.

Решение 2 (это скорее предложение): используйте генератор вместо массива, например:

function* promisesGenerator() {
  yield emulate(3, 2000);
  yield emulate(1, 500);
  yield emulate(2, 1000);
}

async function stepByStepResolve() {
  try {
    for await (const promise of promisesGenerator())
      console.log(promise);
  } catch (e) {
    console.log('Err:', e);
  }
}

stepByStepResolve();

Это предотвратит создание обещаний до for loop, и будут создаваться один за другим по мере выполнения итераций по генератору.

Другие вопросы по тегам