Stop all active ajax requests in jQuery

前端 未结 16 907
自闭症患者
自闭症患者 2020-11-22 13:51

I have a problem, when submitting a form all active ajax request fail, and that triggers error event.

How to stop all active ajax requests in jQuery without trigerri

相关标签:
16条回答
  • 2020-11-22 14:23

    Give each xhr request a unique id and store the object reference in an object before sending. Delete the reference after an xhr request completes.

    To cancel all request any time:

    $.ajaxQ.abortAll();
    

    Returns the unique ids of canceled request. Only for testing purposes.

    Working function:

    $.ajaxQ = (function(){
      var id = 0, Q = {};
    
      $(document).ajaxSend(function(e, jqx){
        jqx._id = ++id;
        Q[jqx._id] = jqx;
      });
      $(document).ajaxComplete(function(e, jqx){
        delete Q[jqx._id];
      });
    
      return {
        abortAll: function(){
          var r = [];
          $.each(Q, function(i, jqx){
            r.push(jqx._id);
            jqx.abort();
          });
          return r;
        }
      };
    
    })();
    

    Returns an object with single function which can be used to add more functionality when required.

    0 讨论(0)
  • 2020-11-22 14:23

    Just as important: say you want to log off and you are generating new requests with timers: because session data is renewed with each new bootstrap (maybe you can tell I am talking Drupal, but this could be any site that uses sessions)... I had to go through all my scripts with a search and replace, cause I had a ton of stuff running in different cases: global variables at the top:

    var ajReq = [];
    var canAj = true;
    function abort_all(){
     for(x in ajReq){
        ajReq[x].abort();
        ajReq.splice(x, 1)
     }
     canAj = false;
    }
    function rmvReq(ranNum){
     var temp = [];
     var i = 0;
     for(x in ajReq){
        if(x == ranNum){
         ajReq[x].abort();
         ajReq.splice(x, 1);
        }
        i++;
     }
    }
    function randReqIndx(){
     if(!canAj){ return 0; }
     return Math.random()*1000;
    }
    function getReqIndx(){
     var ranNum;
     if(ajReq.length){
        while(!ranNum){
         ranNum = randReqIndx();
         for(x in ajReq){
        if(x===ranNum){
         ranNum = null;
        }
         }
        }
        return ranMum;
     }
     return randReqIndx();
    }
    $(document).ready(function(){
     $("a").each(function(){
        if($(this).attr('href').indexOf('/logout')!=-1){          
         $(this).click(function(){
        abort_all();                 
         });
        }
     })
    });
    // Then in all of my scripts I wrapped my ajax calls... If anyone has a suggestion for a 
        // global way to do this, please post
    var reqIndx = getReqIndx();
    if(reqIndx!=0){
    ajReq[reqIndx] = $.post(ajax, { 'action': 'update_quantities', iids:iidstr, qtys:qtystr },  
    function(data){
     //..do stuff
     rmvReq(reqIndx);
     },'json');
    }
    
    0 讨论(0)
  • 2020-11-22 14:25

    Throwing my hat in. Offers abort and remove methods against the xhrPool array, and is not prone to issues with ajaxSetup overrides.

    /**
     * Ajax Request Pool
     * 
     * @author Oliver Nassar <onassar@gmail.com>
     * @see    http://stackoverflow.com/questions/1802936/stop-all-active-ajax-requests-in-jquery
     */
    jQuery.xhrPool = [];
    
    /**
     * jQuery.xhrPool.abortAll
     * 
     * Retrieves all the outbound requests from the array (since the array is going
     * to be modified as requests are aborted), and then loops over each of them to
     * perform the abortion. Doing so will trigger the ajaxComplete event against
     * the document, which will remove the request from the pool-array.
     * 
     * @access public
     * @return void
     */
    jQuery.xhrPool.abortAll = function() {
        var requests = [];
        for (var index in this) {
            if (isFinite(index) === true) {
                requests.push(this[index]);
            }
        }
        for (index in requests) {
            requests[index].abort();
        }
    };
    
    /**
     * jQuery.xhrPool.remove
     * 
     * Loops over the requests, removes it once (and if) found, and then breaks out
     * of the loop (since nothing else to do).
     * 
     * @access public
     * @param  Object jqXHR
     * @return void
     */
    jQuery.xhrPool.remove = function(jqXHR) {
        for (var index in this) {
            if (this[index] === jqXHR) {
                jQuery.xhrPool.splice(index, 1);
                break;
            }
        }
    };
    
    /**
     * Below events are attached to the document rather than defined the ajaxSetup
     * to prevent possibly being overridden elsewhere (presumably by accident).
     */
    $(document).ajaxSend(function(event, jqXHR, options) {
        jQuery.xhrPool.push(jqXHR);
    });
    $(document).ajaxComplete(function(event, jqXHR, options) {
        jQuery.xhrPool.remove(jqXHR);
    });
    
    0 讨论(0)
  • 2020-11-22 14:26

    Using ajaxSetup is not correct, as is noted on its doc page. It only sets up defaults, and if some requests override them there will be a mess.

    I am way late to the party, but just for future reference if someone is looking for a solution to the same problem, here is my go at it, inspired by and largely identical to the previous answers, but more complete

    // Automatically cancel unfinished ajax requests 
    // when the user navigates elsewhere.
    (function($) {
      var xhrPool = [];
      $(document).ajaxSend(function(e, jqXHR, options){
        xhrPool.push(jqXHR);
      });
      $(document).ajaxComplete(function(e, jqXHR, options) {
        xhrPool = $.grep(xhrPool, function(x){return x!=jqXHR});
      });
      var abort = function() {
        $.each(xhrPool, function(idx, jqXHR) {
          jqXHR.abort();
        });
      };
    
      var oldbeforeunload = window.onbeforeunload;
      window.onbeforeunload = function() {
        var r = oldbeforeunload ? oldbeforeunload() : undefined;
        if (r == undefined) {
          // only cancel requests if there is no prompt to stay on the page
          // if there is a prompt, it will likely give the requests enough time to finish
          abort();
        }
        return r;
      }
    })(jQuery);
    
    0 讨论(0)
  • 2020-11-22 14:28
    var Request = {
        List: [],
        AbortAll: function () {
            var _self = this;
            $.each(_self.List, (i, v) => {
                v.abort();
            });
        }
    }
    var settings = {
        "url": "http://localhost",
        success: function (resp) {
            console.log(resp)
        }
    }
    
    Request.List.push($.ajax(settings));
    

    whenever you want to abort all the ajax request, you just need call this line

    Request.AbortAll()
    
    0 讨论(0)
  • 2020-11-22 14:32

    Here's how to hook this up on any click (useful if your page is placing many AJAX calls and you're trying to navigate away).

    $ ->
        $.xhrPool = [];
    
    $(document).ajaxSend (e, jqXHR, options) ->
        $.xhrPool.push(jqXHR)
    
    $(document).ajaxComplete (e, jqXHR, options) ->
        $.xhrPool = $.grep($.xhrPool, (x) -> return x != jqXHR);
    
    $(document).delegate 'a', 'click', ->
        while (request = $.xhrPool.pop())
          request.abort()
    
    0 讨论(0)
提交回复
热议问题