繁体   English   中英

使用$ http拦截器重试请求

[英]Retry request with $http interceptor

我确信有一种简单的方法可以做我想做的事情,我只是无法绕过它。 如果失败,我怎样才能获得角度的http拦截器来重试请求? 我想我必须在请求中建立某种承诺吗? 然后在响应中我将不得不检查响应是否是错误,如果是,那么做出承诺吗? 怎么做的? 我一直试图改变这里的例子: http//docs.angularjs.org/api/ng.$http

我试图使用拦截器的原因是因为我需要在请求URL中添加令牌和其他一些东西,以及处理xdr的一些事情。

这是一个$ http拦截器(立即)重放超时请求(即响应状态0)。 构建此示例有两个非显而易见的(对我来说)元素:

  1. 如何从拦截器中调用$ http - 简单地将$ http添加到依赖项列表中并不能用作循环依赖项的角度抱怨
  2. 如何从响应对象引用原始请求以重试它

这个答案解决了这两个主题,但涉及的更多,因此我在下面添加了简化版本。

joinApp.factory('httpResponseErrorInterceptor',function($q, $injector) {
  return {
    'responseError': function(response) {
      if (response.status === 0) {
        // should retry
        var $http = $injector.get('$http');
        return $http(response.config);
      }
      // give up
      return $q.reject(response);
    }
  };
});

joinApp.config(function($httpProvider) {
  $httpProvider.interceptors.push('httpResponseErrorInterceptor');
});

在实际实现中,您可能需要更复杂的http响应代码处理,重试次数的限制等。

为了完整起见,这里是mygzi的一个版本, 其中包含重试延迟:

.factory('httpResponseErrorInterceptor', ['$injector', '$q', '$timeout', function($injector, $q, $timeout) {
  return {
    'responseError': function(response) {
      if (response.status === 0) {
        return $timeout(function() {
          var $http = $injector.get('$http');
          return $http(response.config);
        }, 15000);
      }
      return $q.reject(response);
    }
  };
}])

.config(function($httpProvider) {
  $httpProvider.interceptors.push('httpResponseErrorInterceptor');
});

$timeout返回一个使用函数参数返回的promise完成的promise,因此我们可以方便地返回$timeout包含的$http调用。

我已经为我之前写过的应用做了这个。 要在函数中重写$ http用法(或者最好在服务中,以便您可以轻松地重用它)。 如果请求失败,请再次调用该函数。

然后诀窍是将promise对象与每个请求一起传递。 如果您为每个请求创建一个新的promise,那么它将与您返回给原始调用者的那个不匹配,因此一旦请求通过,原始调用者将无法获得其promise。

所以它是这样的(请注意,延迟对象在每次重试时都会传递):

app.service('HttpService', ['$q', function($q) {
  this.makeRequest = _makeRequest;

  function _makeRequest(url, data, deffered) {
    // We want to keep the same promise for each request, so we don't loose track
    if (deferred === undefined) {
      deferred = $q.defer();
    }

    // Now make the request
    $http({...}).success(...).error(
      function(){
        // If some condition
        _makeRequest(url, data, deffered);
      }
    )

    // Lastly return the promise
    return deferred.promise;
  }
}])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM