Можно ли прикрепить несколько обработчиков ошибок к одному обещанию?

0

Я использую угловой сервис $ http для проекта. Прежде чем завершить проект, я заметил, что .success вызовы .success и .error устарели. Итак, теперь у нас есть .then и .catch, отлично.

У меня есть служба, которая обертывает вызовы определенному API. Внутри этой службы я хотел "установить" обработчик ошибок по умолчанию в случае несанкционированного запроса. Я делал это так:

post = function(encodedData ,headers ,url ) {
    headers.Accept = '*/*';

        this.setAutentication();

    return $http({
      'url': url,
      'method': 'POST',
      'data': encodedData,
      'headers': headers
    }).error( this.callUnauthorizedHandler.bind(this) );
  };

Как вы можете видеть, я возвращаю обещание $ http с прикрепленным обработчиком ошибок. Поскольку обратный вызов .error возвращает оригинальное обещание, все работает как шарм. Теперь я должен сначала сэкономить обещание переменной, присоединить обработчик ошибок, используя catch, а затем вернуть обещание. Не большая проблема, но я чувствую, что нет никакого способа привязать несколько обработчиков ошибок к одному обещанию, поэтому, если я добавлю еще одно предложение catch, я думаю, что буду перезаписывать уже установленный. Это верно? Каков правильный способ управления этим? Все, что я прочитал о обещаниях, не указывает, является ли эта идея действительной или абсолютно глупой.

РЕДАКТИРОВАТЬ:

Я нашел этот ответ: qaru.site/questions/8177371/... Кажется, что я должен выбросить ошибку из моего обработчика ошибок по умолчанию, если он теперь способен обрабатывать ошибку сам по себе, но я не уверен в этом.

  • 0
    Вы можете просто return $http({...}).catch(this.callUnauthorizedHandler...)
  • 0
    Это первое, что я попробовал, но оно не возвращает первоначальное обещание. Он возвращает то, что является результатом предложения catch.
Показать ещё 6 комментариев
Теги:

1 ответ

2
Лучший ответ

Способ обещает, что распространение ошибок прекратится после первого улова.

somePromise().then( /* ... */ ).catch( function () {
    console.log( 'Error 1' );
} ).catch( function () {
    // Will not execute
    console.log( 'Error 2' );
} );



// On the other hand, in this case...
var p = somePromise().then( /* ... */ );

p.catch( function () {
    console.log( 'Error 1' );
} );

p.catch( function () {
    // Will execute
    console.log( 'Error 2' );
} );

Это происходит потому, что обещание, полученное от улова, на самом деле является другим объектом.

var p = somePromise.then( /*...*/ );

var x = p.catch( /*...*/ );

p === x // False

Это означает, что каждый раз, когда вы вызываете .then (.catch является сокращением для .then( null, fn )), вы возвращаете новое обещание.

Итак, скажем, вы хотели перехватить ошибку и допустить ее распространение. Есть два пути.

Пример 1

var p = somePromise();

p.catch( /*...*/ );

return p;

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

Пример 2 Предпочтительный

return somePromise().then( /*...*/ ).catch( function ( reason ) {
   this.callUnauthorizedHandler( reason );

   // Here we can leverage the fact that all promises 
   // return a new promise, so we can just forge a promise 
   // that will reject right away with the value we want
   return $q.reject( reason );
} );
  • 0
    Большое спасибо за ваше очень подробное объяснение. Обратите внимание, что я хочу обработать только один конкретный тип ошибки по умолчанию и оставить полное управление обещанием для методов / функций, получающих его, поэтому я не буду вызывать никакие .then из метода, возвращающего обещание. Я думаю, что лучший подход в моей ситуации - это какое-то среднее решение между примером 1 и двумя. Установите catch оцените ошибку и, если она не может быть обработана, верните $q.reject(reason) . Должен ли я вернуть обещание, закованное в улов? Вот как я это сделаю: plnkr.co/edit/qEmiX8sd5mFdVX6zCqi0
  • 0
    Да, вы должны вернуть обещание, созданное уловом, как в PLNKR.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню