Angular - 使用Restangular时中止ajax请求

时间:2014-02-03 22:02:06

标签: angularjs restangular

我有一个调用角度服务的方法,因此通过服务发出ajax请求。我需要确保如果多次调用它,则中止先前的请求(如果尚未解决的话)。

此方法可以多次调用。此方法实际上来自ngTableParams上的ngTable:

getData = function($defer, params) {

      myService.getRecord(params).then(function(res){ 
             ...
             $defer.resolve(res.Records);
      }); 
}

以下是该服务的方法:

this.getRecords = function(params) {
    ...

    return Restangular
          .all('/api/records')
          .post(filters);
};

如果ngTable进行3次调用,我希望中止前2次(除非它们返回得太快以至于它已经解决)

2 个答案:

答案 0 :(得分:25)

您可以通过$http配置属性中止timeout调用,该属性可以是Promise,在解析后中止请求。

所以在restangular中,你可以这样做

var abort = $q.defer();
Restangular.one('foos', 12345).withHttpConfig({timeout: abort.promise}).get();
abort.resolve();

例如,要将其与您的用例集成,您可以在服务中使用它:

var abortGet;

this.getRecords = function(params) {
  ...
  if (abortGet) abortGet.resolve();
  abortGet = $q.defer();
  return Restangular
    .all('/api/records')
    .withHttpConfig({timeout: abortGet.promise})
    .post(filters);
}

这样调用getRecords总是会中止之前的调用,如果尚未解决的话!

希望这有帮助!

答案 1 :(得分:1)

如果您想在更改UI路由器的状态时中止所有http请求,这是另一种方法:

angular
    .run(function(HttpHandlerSrv) {
        HttpHandlerSrv.abortAllRequestsOn('$stateChangeSuccess');
        HttpHandlerSrv.R.setFullRequestInterceptor(function(element, operation, route, url, headers, params, httpConfig) {
            httpConfig = httpConfig || {};
            if(httpConfig.timeout === undefined) {
                httpConfig.timeout = HttpHandlerSrv.newTimeout();
            }
            return { element: element, params: params, headers: headers, httpConfig: httpConfig };
        });
    })

    .factory('HttpHandlerSrv', HttpHandlerSrv);


    /** ngInject */
    function HttpHandlerSrv($q, $rootScope, Restangular) {
        var requests = [];

        return {
            R: Restangular,
            newTimeout: newTimeout,
            abortAllRequests: abortAllRequests,
            abortAllRequestsOn: abortAllRequestsOn
        };

        function newTimeout() {
            var request = $q.defer();
            requests.push(request);
            return request.promise;
        }

        function abortAllRequests() {
            angular.forEach(requests, function(request) {
                request.resolve();
            });
            requests = [];
        }

        function abortAllRequestsOn(event) {
            $rootScope.$on(event, function(event, newUrl, oldUrl) {
                if(newUrl !== oldUrl) { abortAllRequests(); }
            });
        }
    }