Какие ошибки обнаруживают функции catch () и «обработчик ошибок» (successHandler, faultHandler)? - PullRequest
1 голос
/ 22 апреля 2019

Я изучаю Обещания, чтобы лучше понять, прежде чем пытаться использовать Firebase. Я новичок, и я прочитал следующее в отношении catch():

  • Ссылка одна : статья с некоторыми упражнениями
  • Ссылка два : вопрос в SO относительно того, почему нам всегда нужен catch() после цепи Promise
  • Ссылка три : вопрос в SO относительно разницы catch() и then()

Из того, что я прочитал, я сделал следующие выводы:

  • catch() необходимо при каждой цепочке Promise в случае возникновения «непредвиденных исключений». Кажется, что эти «неожиданные исключения» могут быть обнаружены failureHandler моего then. Тем не менее, он не может отличить «нормальный отказ» от этих типов отказов. Я предполагаю, что одно из этих «неожиданных исключений» - это когда вы пытаетесь получить доступ к какому-либо свойству null элемента.
  • Кажется, что я также могу создать цепочку then(successHandler, failureHandler), а затем перейти к блоку catch(), чтобы обеспечить более точное управление, как упомянуто в link two . Это полезно, когда я хочу сделать что-то еще, когда что-то выходит из строя («нормальный сбой» в данном случае, а не «неожиданные исключения») и передать отклоненное Обещание следующей then для обработки, что потенциально может привести к совершенно отличным результатам от В результате неудачная часть прошла успешно. Я также могу ловить «неожиданные исключения», используя catch() в конце цепочки на случай, если внутри моего successHandler или failureHandler.

Как вы можете видеть из моих выводов, я очень мало понимаю, какие ошибки могут произойти. Я упомянул исключение null в качестве одного из примеров "неожиданных исключений" (верно ли это предположение?). Однако какие другие ошибки обнаруживает failureHandler и какие другие «неожиданные исключения» обнаруживает catch()?

Я также упоминал выше, что [then] не может отличить нормальный отказ от этих типов отказов . Это верно? Если это так, то почему это важно?

EDIT

После прочтения, кажется, что если Promise отклонен в верхней части цепочки, последующие действия then игнорируются, и я немедленно перехожу к блоку catch(). Это означает, что мой вывод выше: Это полезно, когда я хочу сделать что-то еще, когда что-то не получается, и передать отклоненное обещание следующему then для обработки неверно. Если это так, если у меня уже есть catch() в конце моей цепочки, мне больше не нужен failureHandler для каждого из моих then блоков. Тем не менее, это упомянуто в третьей ссылке:

Аргумент в том, что обычно вы хотите отлавливать ошибки на каждом этапе обработка, и что вы не должны использовать его в цепях. ожидается, что у вас есть только один последний обработчик, который обрабатывает все ошибки - в то время как при использовании «антипаттерна» ошибки в некоторых тогда обратные вызовы не обрабатываются.

Однако этот шаблон на самом деле очень полезен: когда вы хотите обработать ошибки, которые произошли именно на этом шаге, и вы хотите сделать что-то совершенно иное, когда не произошло ошибок - то есть когда ошибка необратима Имейте в виду, что это разветвляет ваш контроль течь. Конечно, это иногда желательно.

Я пришел к выводу, что отклоненное Обещание будет передано следующему then для обработки, потому что я прочитал выше. Так что же значит , и вы хотите сделать что-то совершенно другое, если ошибки не произошло - то есть, когда ошибка неустранимая означает?

1 Ответ

1 голос
/ 22 апреля 2019

Из MDN Я понимаю, что между двумя способами объявления обработчика отклонения нет реальной разницы.

Для успеха очевидно, что мы перейдем к обработчику выполнения:

var promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('success');
  }, 300);
}).then(function(success) {
  console.log(0, success)
}, function(failure) {
  console.log(1, failure)
}).catch(function(failure) {
  console.log(2, failure)
});

Для отклонения мы перейдем к первому обработчику отклонения.
При отклонении обещания:

var promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    reject('failure');
  }, 300);
}).then(function(success) {
  console.log(0, success)
}, function(failure) {
  console.log(1, failure)
}).catch(function(failure) {
  console.log(2, failure)
});

При выдаче ошибки:

var promise = new Promise(function(resolve, reject) {
  throw "throw";
}).then(function(success) {
  console.log(0, success)
}, function(failure) {
  console.log(1, failure)
}).catch(function(failure) {
  console.log(2, failure)
});

Обратите внимание, что блок catch игнорируется, потому что он прикован к обещанию первого обработчика (выполнение или отклонение).
Если мы изменим его, чтобы отклонить или повторно выбросить, мы получим обработчик в catch.

var promise = new Promise(function(resolve, reject) {
  throw "re-throw";
}).then(function(success) {
  console.log(0, success)
}, function(failure) {
  console.log(1, failure)
  throw failure;
}).catch(function(failure) {
  console.log(2, failure)
});

Это изображение из ссылки выше хорошо описывает это. Image from MDN link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...