How can I extend $q promise in Angularjs with a .success and .error

后端 未结 3 1594
有刺的猬
有刺的猬 2020-12-28 15:37

I wrote this little code in a custom service in AngularJS.

In my service:

        var deferred = $q.defer();
        var promise = deferred.promise;         


        
3条回答
  •  时光取名叫无心
    2020-12-28 16:25

    IMHO, @jessegavin 's decoration of $q is not perfect, it shouldn't return origin promise in success&error function. It will lose feature of flatten the callback pyramid.

    And it can't split response data to success&error function $httpPromise dose.

    for example

    //can't do this..
    somePromise.success(function(){
      return $http.get(...)//another primise
    }).success(function(data){
      //data from $http.get..
    })
    

    Here is my version, it will recognize http response and will return the next promise. Make your own $q have the same behavior like $httpPromise

    $provide.decorator('$q', function($delegate) {
      function httpResponseWrapper(fn) {
        return function(res) {
          if (res.hasOwnProperty('data') && res.hasOwnProperty('status') && res.hasOwnProperty('headers') && res.hasOwnProperty('config') && res.hasOwnProperty('statusText')) {
            return fn(res.data, res.status, res.headers, res.config, res.statusText);
          } else {
            return fn(res);
          }
        };
      };
      function decorator(promise) {
        promise.success = function(fn) {
          return decorator(promise.then(httpResponseWrapper(fn)));
        };
        promise.error = function(fn) {
          return decorator(promise.then(null, httpResponseWrapper(fn)));
        };
        return promise;
      };
      var defer = $delegate.defer;
      $delegate.defer = function() {
        var deferred = defer();
        decorator(deferred.promise);
        return deferred;
      };
      return $delegate;
    });
    

提交回复
热议问题