当$ .each和array.splice(i)保持在一起时,JQuery处理索引错误中的数组
最近我在互联网上搜索一些可以处理废弃的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的值增加,因此获得cought的元素将是不同的(或者不是预期的)。
例如,考虑array = [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是能正确完成工作的人,但我仍然无法弄清楚如何。
代码“有效”,但没有做它应该做的事情。 该方法称为abortAll
,它会中止所有XHR,但只清除一半的数组。 它应该真正删除它中止的所有项目,但它不会。
jQuery each
都会获取数组的副本并迭代它,所以我仍然会从0复制到(复制)数组中的最后一个索引,即使从原始数组中删除了元素。
但它仍然出错,因为splice
作用于原始数组,它将元素移动到该数组中的前面索引。 但是,另一方面,我不断增加,所以两个元素中的一个将在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; });