Выполнение затем после улова
У меня есть следующая скрипка:
http://jsfiddle.net/thelgevold/3uv9nnjm/6/
angular.module('hello',[]).controller('helloController',function($q){
console.clear();
function someService(){
var deferred = $q.defer();
deferred.reject({e:'error'});
return deferred.promise;
}
function callService(){
return someService().then(function(obj){
console.log('first then');
}).
catch(function(e){
console.log('error1');
var deferred = $q.defer();
deferred.reject({e:'error'});
return deferred.promise;
});
}
callService().catch(function(e){
console.log('error2');
}).then(function(e){
console.log('second then');
});
});
Это, по сути, просто быстрый $q обещающий POC. Мой вопрос: почему последнее предложение вызывается, когда обещание отвергается? Выход выглядит следующим образом:
Error1
Error2
секунд, затем
Я понимаю, почему печатается error1/error2, но я думал, что вторая строка не должна печататься, поскольку обещание было отклонено. Я думал, что он будет опускать "второй тогда" по той же причине, что и "первым тогда".
Любые мысли?
Ответы
Ответ 1
Прежде чем начать, не делайте этого:
var deferred = $q.defer();
deferred.reject({e:'error'});
return deferred.promise;
Сделайте это:
return $q.reject({e:'error'});
Или предпочтительно это:
return $q.reject(new Error('error'));
Остерегайтесь отложенного антипаттера.
Теперь, для ответа на ваш вопрос.
.catch()
после вашего вызова callService()
обнаруживает ошибку и не создает новую ошибку. Он по существу "обработал" ошибку, и следующий обработчик .then()
может быть вызван.
Синхронный эквивалент кода вашего примера:
function someService() {
throw { e: 'error' };
}
function callService() {
try {
var obj = someService();
console.log('first then');
} catch (e) {
console.log('error1');
throw { e: 'error' };
}
}
var e;
try {
e = callService();
} catch (e) {
console.log('error2');
}
console.log('second then');