Why is my Deferred method not triggering the error method?
I created this simple code to simulate resolve
, reject
, error
:
function $http(){
var core = {
factory : function (action) {
var promise = new Promise( function (resolve, reject) {
if (action==='resolve') resolve({r:'Resolved'});
if (action==='error') throw Error("error");
if (action==='reject') reject({r:'Reject'});
});
return promise;
}
};
return {
'simulate' : function(a) {
return core.factory(a);
}
};
}
var callback = {
success : function(data){
console.log(1, 'success', data.r);
},
error : function(data){
console.log(2, 'error',data.r);
},
reject : function(data){
console.log(3, 'reject', data.r);
}
};
Now let's call them:
$http().simulate('resolve')
.then(callback.success,callback.reject)
.catch(callback.error); //"success" "Reolved"
$http().simulate('reject')
.then(callback.success,callback.reject)
.catch(callback.error); //"reject" "Reject"
$http().simulate('error')
.then(callback.success,callback.reject)
.catch(callback.error);//"reject" undefined
As you can see, both reject / resolve works.
Question:
Why not:
error : function(data){
console.log(2, 'error',data.r);
}
Does the function run when I simulate error
?
source to share
Why not
error : function(data){ console.log(2, 'error',data.r); }
when do i imitate
error
?
According to the ECMA Script 6 Promise specifications, when you create a Promise constructor with a constructor Promise
, the generated Promise object will have two internal slots, [[PromiseFulfillReactions]]
and [[PromiseRejectReactions]]
, which are actually lists, and they will hold all the corresponding match and reject handlers respectively.
When you attach a handler then
to a promise object, the fulfillment handler will be added to the list [[PromiseFulfillReactions]]
and the reject handler will be added to the list [[PromiseRejectReactions]]
. When the promise is fulfilled, all handlers in [[PromiseFulfillReactions]]
will be called, similarly, when the state changes from pending
to rejected
, all rejection handlers will be called.
In both cases
$http().simulate('reject')
.then(callback.success, callback.reject)
.catch(callback.error); //"reject" "Reject"
$http().simulate('error')
.then(callback.success, callback.reject)
.catch(callback.error); //"reject" undefined
$http().simulate('reject')
and $http().simulate('error')
create new promises, and when you attach a handler then
, callback.success
and callback.reject
will be added to the list of matching reactions. In both cases, tossing error
and rejecting will be considered as rejecting only the promise. Because [[PromiseRejectReactions]]
there is only one handler for both executable cases. This is why it callback.reject
is only called in both cases.
What if you have defined the latter case like
$http().simulate('error')
.then(callback.success)
.catch(callback.error);
The handler now then
has no onRejected handler. But it's important to note here that all handlers then
will create new promises and return them . So, since the reject handler is not available with the current one then
, it will create a rejected promise and return it. And it's just syntactic sugar for . A rejected promise rejects the list of reactions, gets a function, and will be called because the promise is rejected. .catch(callback.error)
.then(undefined, callback.error)
callback.error
source to share