简体   繁体   English

当$ .each和array.splice(i)放在一起时,jQuery会处理索引错误之外的数组

[英]JQuery handles array out of index errors when $.each and array.splice(i) are kept together

Recently I was searching in internet for some code which can handle abandoned ajax/xhr calls. 最近,我在互联网上搜索一些可以处理废弃的ajax / xhr调用的代码。

And this is what I found : 这就是我发现的

$.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 code works fine , but one line in it confuses me, I doubt that there is some logical error, but somehow works perfect. 这段代码可以正常工作 ,但是其中的一行让我感到困惑,我怀疑是否存在一些逻辑错误,但是以某种方式可以完美运行。

Below is the part which confuses me, 以下是令我困惑的部分,

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

Iterating through a for loop and takes i'th element and removes it from array. 遍历一个for循环并获取第i个元素,并将其从数组中删除。

Now the total length of the array is reduced and the indexes of the elements also reduces, as first member is removed from it. 现在,随着从数组中删除第一个成员,数组的总长度减少了,元素的索引也减少了。

Then in the next iteration, value of i is increased, so the element which is getting cought will be different (or not as expected). 然后,在下一次迭代中,i的值将增加,因此正在等待处理的元素将有所不同(或不符合预期)。

For example consider array = [1,2,3,4,5,6,7,8,9,10]; 例如考虑数组= [1,2,3,4,5,6,7,8,9,10];

Iteration 1 迭代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]

Iteration 2 迭代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]

Iteration 3 迭代3

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

Iteration 4 迭代4

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

Iteration 5 迭代5

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

Iteration 6 迭代6

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

** Here comes the trouble. **麻烦来了。

Note : My computer is able to understand this code and execute it correctly, but the trouble is with my brain, who is not ready to accept this part :-( 注意:我的计算机能够理解该代码并正确执行它,但是问题出在我的大脑上,他不准备接受这一部分:-(

I believe that the $.each is the one who makes the job correctly, but still I am not able to figure it how. 我相信$ .each是正确完成这项工作的人,但是我仍然无法弄清楚它是如何做到的。

The code "works", but is not doing what it is supposed to do. 代码“有效”,但没有执行应做的工作。 The method is called abortAll , and it does abort all XHRs, but only clears half of the array. 该方法称为abortAll ,它中止所有XHR,但只会清除数组的一半。 It should really remove all items it aborts, which it doesn't. 它实际上应该删除它中止的所有项目,但不是。

jQuery each will take a copy of the array and iterate that, so i will still go from 0 to the last index in the (copied) array, even though elements are removed from the original array. each jQuery都会获取该数组的一个副本并对其进行迭代,因此,即使从原始数组中删除了元素, 仍然会从0到(复制的)数组中的最后一个索引。

But it still goes wrong, because the splice acts on the original array, which moves elements to preceding indexes in that array. 但是它仍然会出错,因为splice作用于原始数组,该数组将元素移至该数组中的先前索引。 But i , on the other hand, keeps increasing, so one in two elements will survive the splice . ,在另一方面,不断增加,所以有二分之一的元素将生存的splice

The abortAll could be corrected to this: 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); 
    });
});

... but really, it can be done simply like this: ...但实际上,可以像这样简单地完成:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM