How to cancel an $http request in AngularJS?

前端 未结 8 964
面向向阳花
面向向阳花 2020-11-22 09:49

Given a Ajax request in AngularJS

$http.get(\"/backend/\").success(callback);

what is the most effective way to cancel that request if anot

8条回答
  •  深忆病人
    2020-11-22 10:29

    Cancelling Angular $http Ajax with the timeout property doesn't work in Angular 1.3.15. For those that cannot wait for this to be fixed I'm sharing a jQuery Ajax solution wrapped in Angular.

    The solution involves two services:

    • HttpService (a wrapper around the jQuery Ajax function);
    • PendingRequestsService (tracks the pending/open Ajax requests)

    Here goes the PendingRequestsService service:

        (function (angular) {
        'use strict';
        var app = angular.module('app');
        app.service('PendingRequestsService', ["$log", function ($log) {            
            var $this = this;
            var pending = [];
            $this.add = function (request) {
                pending.push(request);
            };
            $this.remove = function (request) {
                pending = _.filter(pending, function (p) {
                    return p.url !== request;
                });
            };
            $this.cancelAll = function () {
                angular.forEach(pending, function (p) {
                    p.xhr.abort();
                    p.deferred.reject();
                });
                pending.length = 0;
            };
        }]);})(window.angular);
    

    The HttpService service:

         (function (angular) {
            'use strict';
            var app = angular.module('app');
            app.service('HttpService', ['$http', '$q', "$log", 'PendingRequestsService', function ($http, $q, $log, pendingRequests) {
                this.post = function (url, params) {
                    var deferred = $q.defer();
                    var xhr = $.ASI.callMethod({
                        url: url,
                        data: params,
                        error: function() {
                            $log.log("ajax error");
                        }
                    });
                    pendingRequests.add({
                        url: url,
                        xhr: xhr,
                        deferred: deferred
                    });            
                    xhr.done(function (data, textStatus, jqXhr) {                                    
                            deferred.resolve(data);
                        })
                        .fail(function (jqXhr, textStatus, errorThrown) {
                            deferred.reject(errorThrown);
                        }).always(function (dataOrjqXhr, textStatus, jqXhrErrorThrown) {
                            //Once a request has failed or succeeded, remove it from the pending list
                            pendingRequests.remove(url);
                        });
                    return deferred.promise;
                }
            }]);
        })(window.angular);
    

    Later in your service when you are loading data you would use the HttpService instead of $http:

    (function (angular) {
    
        angular.module('app').service('dataService', ["HttpService", function (httpService) {
    
            this.getResources = function (params) {
    
                return httpService.post('/serverMethod', { param: params });
    
            };
        }]);
    
    })(window.angular);
    

    Later in your code you would like to load the data:

    (function (angular) {
    
    var app = angular.module('app');
    
    app.controller('YourController', ["DataService", "PendingRequestsService", function (httpService, pendingRequestsService) {
    
        dataService
        .getResources(params)
        .then(function (data) {    
        // do stuff    
        });    
    
        ...
    
        // later that day cancel requests    
        pendingRequestsService.cancelAll();
    }]);
    
    })(window.angular);
    

提交回复
热议问题