Как поймать отклоненное обещание в новом узле выражения 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)
в promises
array, обещание создается и будет отклонено на следующей фазе цикла событий, за исключением случаев, когда вы слушаете его и обрабатываете до этого. Теперь в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
, и будут создаваться один за другим по мере выполнения итераций по генератору.