JQuery обрабатывает массив из ошибок индекса, когда $.each и array.splice(i) сохраняются вместе

Недавно я искал в Интернете какой-то код, который может обрабатывать заброшенные вызовы ajax/xhr.

И вот что я нашел:

$.xhrPool = [];

$.ajaxSetup({
    beforeSend: function (jqXHR) {
        $.xhrPool.push(jqXHR);
    },
    complete: function (jqXHR) {
        var i = $.xhrPool.indexOf(jqXHR);
        if (i > -1)
            $.xhrPool.splice(i, 1);
    }
});

$.xhrPool.abortAll = function () {
    $(this).each(function (i, jqXHR) {
        jqXHR.abort();
        $.xhrPool.splice(i, 1);// This is the line which makes me confused.
    });
};

Этот код работает отлично, но одна строка в нем меня смущает, я сомневаюсь, что есть некоторая логическая ошибка, но как-то отлично работает.

Ниже приведена часть, которая меня смущает,

$(this).each(function (i, jqXHR) {
        $.xhrPool.splice(i, 1);
});

Итерация через цикл for и принимает i-й элемент и удаляет его из массива.

Теперь общая длина массива уменьшается, а индексы элементов также уменьшаются, поскольку первый элемент удаляется из него.

Затем в следующей итерации значение я увеличивается, поэтому элемент, который получает кучу, будет отличаться (или не так, как ожидалось).

Например, рассмотрим массив = [1,2,3,4,5,6,7,8,9,10];

Итерация 1

array = [1,2,3,4,5,6,7,8,9,10]
i=0
removes 1
new array is [2,3,4,5,6,7,8,9,10]

Итерация 2

array = [2,3,4,5,6,7,8,9,10]
i=1
removes 3
new array is [2,4,5,6,7,8,9,10]

Итерация 3

array = [2,4,5,6,7,8,9,10]
i=2
removes 5
new array is [2,4,6,7,8,9,10]

Итерация 4

array = [2,4,6,7,8,9,10]
i=3
removes 7
new array is [2,4,6,8,9,10]

Итерация 5

array = [2,4,6,8,9,10]
i=4
removes 9
new array is [2,4,6,8,10]

Итерация 6

array = [2,4,6,8,10]
i=5

** Здесь возникает проблема.

Примечание. Мой компьютер способен понять этот код и выполнить его правильно, но проблема с моим мозгом, который не готов принять эту часть: - (

Я считаю, что $.each - это тот, кто правильно выполняет задание, но все же я не могу понять, как это сделать.

Ответ 1

Код "работает", но не выполняет то, что он должен делать. Метод называется abortAll, и он отменяет все XHR, но только очищает половину массива. Он должен действительно удалить все элементы, которые он прерывает, а это не так.

jQuery each возьмет копию массива и повторит ее, поэтому я все равно перейду от 0 к последнему индексу в (скопированном) массиве, даже если элементы будут удалены из исходного массива.

Но это по-прежнему не так, потому что splice действует на исходный массив, который перемещает элементы в предыдущие индексы в этом массиве. Но i, с другой стороны, продолжает расти, поэтому один из двух элементов выдержит splice.

abortAll может быть исправлено:

$.xhrPool.abortAll = function () {
    $(this).each(function (i, jqXHR) {
        jqXHR.abort();
        // the element to be deleted will always be at index 0 in the original array:
        $.xhrPool.splice(0, 1); 
    });
});

... но на самом деле это можно сделать просто так:

$.xhrPool.abortAll = function () {
    $(this).each(function (i, jqXHR) {
        jqXHR.abort();
    });
    $.xhrPool.length = 0;
});