AngularJS में $ http अनुरोध को कैसे रद्द करें?




promise angular-promise (5)

AngularJS में एक अजाक्स अनुरोध को देखते हुए

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

अगर कोई अन्य अनुरोध लॉन्च किया गया है तो अनुरोध रद्द करने का सबसे प्रभावी तरीका क्या है (उदाहरण के लिए समान बैकएंड, विभिन्न पैरामीटर)।


किसी कारण से config.timeout मेरे लिए काम नहीं करता है। मैंने इस दृष्टिकोण का उपयोग किया:

let cancelRequest = $q.defer();
let cancelPromise = cancelRequest.promise;

let httpPromise = $http.get(...);

$q.race({ cancelPromise, httpPromise })
    .then(function (result) {
...
});

और रद्द करने के लिए revequest.resolve () रद्द करें। दरअसल यह अनुरोध रद्द नहीं करता है लेकिन आपको कम से कम अनावश्यक प्रतिक्रिया नहीं मिलती है।

उम्मीद है की यह मदद करेगा।


टाइमआउट संपत्ति के साथ कोणीय $ http अजाक्स को रद्द करना कोणीय 1.3.15 में काम नहीं करता है। उन लोगों के लिए जो इसे ठीक करने की प्रतीक्षा नहीं कर सकते हैं, मैं कोणीय में लिपटे एक jQuery अजाक्स समाधान साझा कर रहा हूं।

समाधान में दो सेवाएं शामिल हैं:

  • HttpService (jQuery अजाक्स फ़ंक्शन के चारों ओर एक रैपर);
  • लंबितRequestsService (लंबित / खुले अजाक्स अनुरोध ट्रैक करता है)

लंबित Requests सेवा सेवा यहां जाती है:

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

एचटीपी सेवा सेवा:

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

जब आप डेटा लोड कर रहे हों तो बाद में आपकी सेवा में आप $ http की बजाय HttpService का उपयोग करेंगे:

(function (angular) {

    angular.module('app').service('dataService', ["HttpService", function (httpService) {

        this.getResources = function (params) {

            return httpService.post('/serverMethod', { param: params });

        };
    }]);

})(window.angular);

बाद में आपके कोड में आप डेटा लोड करना चाहते हैं:

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

यह $ http सेवा को एक निरस्त विधि के साथ सजाने के द्वारा स्वीकृत उत्तर को बढ़ाता है ...

'use strict';
angular.module('admin')
  .config(["$provide", function ($provide) {

$provide.decorator('$http', ["$delegate", "$q", function ($delegate, $q) {
  var getFn = $delegate.get;
  var cancelerMap = {};

  function getCancelerKey(method, url) {
    var formattedMethod = method.toLowerCase();
    var formattedUrl = encodeURI(url).toLowerCase().split("?")[0];
    return formattedMethod + "~" + formattedUrl;
  }

  $delegate.get = function () {
    var cancelerKey, canceler, method;
    var args = [].slice.call(arguments);
    var url = args[0];
    var config = args[1] || {};
    if (config.timeout == null) {
      method = "GET";
      cancelerKey = getCancelerKey(method, url);
      canceler = $q.defer();
      cancelerMap[cancelerKey] = canceler;
      config.timeout = canceler.promise;
      args[1] = config;
    }
    return getFn.apply(null, args);
  };

  $delegate.abort = function (request) {
    console.log("aborting");
    var cancelerKey, canceler;
    cancelerKey = getCancelerKey(request.method, request.url);
    canceler = cancelerMap[cancelerKey];

    if (canceler != null) {
      console.log("aborting", cancelerKey);

      if (request.timeout != null && typeof request.timeout !== "number") {

        canceler.resolve();
        delete cancelerMap[cancelerKey];
      }
    }
  };

  return $delegate;
}]);
  }]);

यह कोड क्या कर रहा है?

अनुरोध रद्द करने के लिए "वादा" टाइमआउट सेट होना चाहिए। यदि HTTP अनुरोध पर कोई टाइमआउट सेट नहीं किया गया है तो कोड "वादा" टाइमआउट जोड़ता है। (यदि एक टाइमआउट पहले से सेट है तो कुछ भी नहीं बदला जाता है)।

हालांकि, वादे को हल करने के लिए हमें "स्थगित" पर एक हैंडल की आवश्यकता है। हम इस प्रकार एक मानचित्र का उपयोग करते हैं ताकि हम बाद में "स्थगित" पुनः प्राप्त कर सकें। जब हम निरस्त विधि को कॉल करते हैं, तो "स्थगित" मानचित्र से पुनर्प्राप्त किया जाता है और फिर हम http अनुरोध को रद्द करने के लिए हल विधि को कॉल करते हैं।

उम्मीद है कि यह किसी की मदद करता है।

सीमाएँ

वर्तमान में यह केवल $ http.get के लिए काम करता है लेकिन आप $ http.post के लिए कोड जोड़ सकते हैं और इसी तरह

कैसे इस्तेमाल करे ...

इसके बाद आप इसका उपयोग कर सकते हैं, उदाहरण के लिए, राज्य परिवर्तन पर, निम्नानुसार ...

rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
  angular.forEach($http.pendingRequests, function (request) {
        $http.abort(request);
    });
  });

यह सुविधा टाइमआउट पैरामीटर के माध्यम से 1.1.5 रिलीज में जोड़ा गया था:

var canceler = $q.defer();
$http.get('/someUrl', {timeout: canceler.promise}).success(successCallback);
// later...
canceler.resolve();  // Aborts the $http request if it isn't finished.

$http साथ जारी अनुरोधों को रद्द करना AngularJS के वर्तमान संस्करण के साथ समर्थित नहीं है। इस क्षमता को जोड़ने के लिए एक पुल अनुरोध खोला गया है लेकिन इस पीआर की समीक्षा अभी तक नहीं की गई है, इसलिए यह स्पष्ट नहीं है कि यह इसे AngularJS कोर में लाने जा रहा है।





cancellation