Почему 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() на самом деле возвращается отклонено.

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