Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
111
rated 0 times [  116] [ 5]  / answers: 1 / hits: 11875  / 10 Years ago, wed, february 11, 2015, 12:00:00

I have the following fiddle:
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');
});

});


It's essentially just a quick $q promise POC. My question is: Why does the last then clause get called when the promise is rejected? The output is as follows:



error1



error2



second then



I understand why error1/error2 are printed, but I thought the second then string should not be printed since the promise was rejected. I thought it would omit second then for the same reason the first then is omitted.
Any thoughts?


More From » angularjs

 Answers
6

Before I get started, don't do this:



var deferred = $q.defer();
deferred.reject({e:'error'});
return deferred.promise;


Do this:



return $q.reject({e:'error'});


Or preferably, this:



return $q.reject(new Error('error'));


Beware the deferred antipattern.



Now, for the answer to your question.



The .catch() after your call to callService() is catching the error and not producing a new error. It has essentially handled the error, and the following .then() handler is free to be called.



The synchronous code equivalent of your example would be:





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');





I think that if you look at it this way, it makes perfect sense.



The relevant text in the Promises/A+ spec is here. For all intents and purposes, you can view the catch handler as the same thing as an onRejected handler:




2.2.7. then must return a promise [3.3].



promise2 = promise1.then(onFulfilled, onRejected);



2.2.7.1. If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).




Basically, your onRejected handler is returning the value undefined, so the promise produced by catch() resolves with the value undefined.


[#39334] Tuesday, February 10, 2015, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
billosvaldor

Total Points: 601
Total Questions: 113
Total Answers: 113

Location: Iceland
Member since Sat, Sep 17, 2022
2 Years ago
;