Get state of Angular deferred?

前端 未结 4 1826
野的像风
野的像风 2020-12-04 19:41

With jQuery deferreds I\'m used to be able to check the current state like this:

var defer = $.Deferred();
defer.state();  //Returns the state of the deferre         


        
4条回答
  •  难免孤独
    2020-12-04 20:12

    The answer to your question is: yes, there is a way. The other answers nicely cover the built-in limitations of $q. However, it's easy to add a state property to $q using the $provide service's decorator function.

      $provide.decorator('$q', function ($delegate) {
        var defer = $delegate.defer;
        $delegate.defer = function() {
          var deferred = defer();
    
          deferred.promise.state = deferred.state = 'pending';
    
          deferred.promise.then(function() {
            deferred.promise.state = deferred.state = 'fulfilled';
          }, function () {
            deferred.promise.state = deferred.state = 'rejected';
          }); 
    
          return deferred;
        };
        return $delegate;
      });
    

    Put this decorator inside of a config block, and all $q-instantiated deferred and promise objects will have a state property with the value pending, fulfilled, or rejected.

    Check out this plunk


    Skeptical?

    you are effectively modifying $q itself, wrapping every deferred with another deferred

    Actually this is not the case. $q's original defer() constructor is called exactly one time. It is simply decorated with additional functionality by internally attaching an event handler via then. [Note that an additional defer object is instantiated as a result of the additional then callback which is automatically created with each deferred object... which is to be expected because this is how angular works internally.]

    this wouldn't work because promises shouldn't be created with deferred but chained from promises that are returned from apis

    Note that this code will decorate every deferred (and thus promise object) which is created by the $q service. This means that any API which utilizes $q will be automatically decorated with the state property. So regardless of how you use $q, whether with some API or on it's own, this solution decorates both the deferred object and the promise, and I have provided the plunk to prove it.


    Production-worthy?

    This approach is unit testable, it's guaranteed not to break any application already using $q, and it's flexible in the sense that you could later add additional decorators to $q without modifying the old one(s).

提交回复
热议问题