0

I've implemented the usual AJAX pool, but when I abort all requests it aborts them at increments of 2 requests, ie. first, third, fifth ... This is basically what I do:

$.ajaxSetup({
  beforeSend: function(jqXHR, settings) {
    $.xhrPool.push(jqXHR);
  },
  complete: function(jqXHR, text) {
    // Remove a completed request from the array
    var index = $.xhrPool.indexOf(jqXHR);
    if (index > -1) {
      $.xhrPool.splice(index, 1);
    }
  },
  error: function(jqXHR, textStatus, errorThrown) {
    // Remove a error request from the array
    var index = $.xhrPool.indexOf(jqXHR);
    if (index > -1) {
      $.xhrPool.splice(index, 1);
    }
  }
});

function abortAll() {
  $.each($.xhrPool, function(key, value) {
    value.abort();
  });
}

If I do a console.log(value) inside the $.each, some of them are undefined. If I do a console.log($.xhrPool) before the $.each, they all look ok.

What am I missing?

Paul
  • 139,544
  • 27
  • 275
  • 264
Alon S
  • 107
  • 13

2 Answers2

2

First of all the complete is called even after an error so you do not need to handle both if you do the same thing.

Secondly, when you abort the error and complete are invoked so the initial array is altered while you are iterating over it (in the $.each) which is a bad pattern in general.

So in your each you are at the 1st element, you abort it (and alter the array to remove the element), then you go to the element with index 2 which is the previously 3rd but now 2nd since the 1st was removed.

Array                      each index                target
[xhr1, xhr2, xhr3, xhr4]       0                      xhr1
[xhr2, xhr3, xhr4]             1                      xhr3
[xhr3, xhr4]                   2                      undefined
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
1

Based on Gaby aka G. Petrioli answer, the best way to actually solve this problem is to create a new array to loop over:

function abortAll() {
  // copying-an-array-of-objects-into-another-array-in-javascript
  // https://stackoverflow.com/questions/16232915
  var calls = Array.from($.xhrPool);

  $.each(calls, function(key, value) {
    value.abort();
  });
}
Erik Philips
  • 53,428
  • 11
  • 128
  • 150