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?

2
  • As you're aborting them, are the complete and error callback happening synchronously? I would expect not, but, maybe
    – Kevin B
    Commented Dec 14, 2017 at 17:28
  • You can use complete instead to remove the item to keep your code DRY. Commented Dec 14, 2017 at 17:35

2 Answers 2

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
3
  • Are you use javascript can run multiple scripts in parallel? If not, it's not possible for error nor complete to run while abortAll Commented Dec 14, 2017 at 17:41
  • 1
    @ErikPhilips they are not run in parallel. Inside the jquery .abort() method the .complete() is called. Commented Dec 14, 2017 at 17:45
  • Gotcha, you are correct, I see what you're saying now. You probably should include an coded answer to solve the problem. Commented Dec 14, 2017 at 17:56
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();
  });
}
1
  • Creating a static instance of xhrPool using Array.from did the trick
    – Alon S
    Commented Dec 18, 2017 at 8:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.