Почему Promise.all() выдает исключение, даже если я .catch() это?
Запуск кода
Promise.all(new Promise((res, rej) => rej('Failure!')))
.catch(() => console.log("It's all okay."))
в Node v12.19.0 регистрирует консоль, но по-прежнему генерирует исключение. Это почему? Я ожидал того же поведения, что и при запуске
new Promise((res, rej) => rej('Failure!'))
.catch(() => console.log("It's all okay."))
Это также будет регистрировать
It's all okay.
на консоль, но не вызывает исключения.
Как я могу поймать отказ в Promise.all()?
Полный вывод консоли:
> Promise.all(new Promise((res, rej) => rej('Failure!'))).catch(() => console.log("It's all okay."))
Promise { <pending> }
> It's all okay.
(node:2872) UnhandledPromiseRejectionWarning: Failure!
(node:2872) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
> new Promise((res, rej) => rej('Failure!')).catch(() => console.log("It's all okay."))
Promise { <pending> }
> It's all okay.
1 ответ
Как указал Bergi в комментариях ...
Если вы выполните свой первый фрагмент кода без оператора catch (или фактически распечатаете обнаруженные ошибки), вы увидите, что происходит.
Promise.all(new Promise((res, rej) => rej('Failure!')))
Возврат:
Promise {<rejected>: TypeError}
Uncaught (in promise) Failure!
Uncaught (in promise) TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
at Function.all (<anonymous>)
at <anonymous>:1:9
Обратите внимание, что первая ошибка - это ошибка, которую мы выдаем, отклоняя обещание.
Вторая ошибка возникает из-за неправильного использования, это ошибка, которую вы поймали.
Ошибка, которую мы выдаем, отклоняя обещание, никогда не перехватывается из-за неправильного использования метода.
Теперь давайте протестируем код с нашим обещанием внутри массива, что является правильным использованием, как указал Barmar в комментариях.
Promise.all([new Promise((res, rej) => rej('Failure!'))])
.catch(() => console.log("It's all okay."))
Возврат:
Promise {<fulfilled>}
It´s all okay.
Итак, мы успешно отлавливаем ошибку отклоненного обещания.
Также стоит отметить, что последнее возвращенное обещание - это обещание, которое
catch()
метод возвращается после выполнения. Это выполнено, поскольку мы успешно выполнили оператор catch, хотя обещание, что
Promise.all()
на самом деле возвращается отклонено.