Angular - прервать запрос ajax при использовании Restangular

У меня есть метод, который вызывает службу angular и, следовательно, делает запрос ajax через службу. Мне нужно убедиться, что если это вызывается несколько раз, предыдущий запрос прерывается (если он еще не был разрешен, то есть).

Этот метод можно вызвать несколько раз. Этот метод выполняется из ngTable на ngTableParams:

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 были прерваны (если, конечно, они не вернулись так быстро, что они были решены)

Ответы

Ответ 1

Вы можете прервать вызовы $http с помощью свойства конфигурации timeout, которое может быть обещанием, которое прерывает запрос при его разрешении.

Итак, в restangular вы можете сделать это, например

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

Чтобы интегрировать его с вашим usecase, например, вы могли бы иметь это в своей службе:

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 всегда отменяет предыдущий вызов, если он еще не был разрешен!

Надеюсь, это поможет!

Ответ 2

Это другой подход, если вы хотите прервать все HTTP-запросы при изменении состояния для UI-маршрутизатора:

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(); }
            });
        }
    }