Я использую угловой сервис $ 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/... Кажется, что я должен выбросить ошибку из моего обработчика ошибок по умолчанию, если он теперь способен обрабатывать ошибку сам по себе, но я не уверен в этом.
Способ обещает, что распространение ошибок прекратится после первого улова.
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 );
} );
.then
из метода, возвращающего обещание. Я думаю, что лучший подход в моей ситуации - это какое-то среднее решение между примером 1 и двумя. Установите catch
оцените ошибку и, если она не может быть обработана, верните $q.reject(reason)
. Должен ли я вернуть обещание, закованное в улов? Вот как я это сделаю: plnkr.co/edit/qEmiX8sd5mFdVX6zCqi0
return $http({...}).catch(this.callUnauthorizedHandler...)