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

?

Full Jsbin

+3


source to share


2 answers


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

+3


source


This is because your method callback.reject

handles the thrown error itself. If you want yours to callback.error

be called, you need to change the method callback.reject

to throw

the error itself, or have one return Promise.reject(data)

.



0


source







All Articles