Sar*_*J S 2 javascript arrays each 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.
});
};
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,但其中的一行让我感到困惑,我怀疑存在一些逻辑错误,但不知何故工作完美。
下面是让我困惑的部分,
$(this).each(function (i, jqXHR) {
$.xhrPool.splice(i, 1);
});
Run Code Online (Sandbox Code Playgroud)
迭代 for 循环并获取第 i 个元素并将其从数组中删除。
现在,数组的总长度减少了,元素的索引也减少了,因为第一个成员被删除了。
Then in the next iteration, value of i is increased, so the element which is getting cought will be different (or not as expected).
For example consider array = [1,2,3,4,5,6,7,8,9,10];
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]
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)
array = [2,4,5,6,7,8,9,10]
i=2
removes 5
new array is [2,4,6,7,8,9,10]
Run Code Online (Sandbox Code Playgroud)
array = [2,4,6,7,8,9,10]
i=3
removes 7
new array is [2,4,6,8,9,10]
Run Code Online (Sandbox Code Playgroud)
array = [2,4,6,8,9,10]
i=4
removes 9
new array is [2,4,6,8,10]
Run Code Online (Sandbox Code Playgroud)
array = [2,4,6,8,10]
i=5
Run Code Online (Sandbox Code Playgroud)
** Here comes the trouble.
注意:我的计算机能够理解这段代码并正确执行它,但问题出在我的大脑上,我还没有准备好接受这部分:-(
我相信 $.each 是正确完成这项工作的人,但我仍然无法弄清楚它是如何实现的。
代码“有效”,但没有做它应该做的事情。调用该方法abortAll,它确实中止所有 XHR,但只清除数组的一半。它确实应该删除它中止的所有项目,但事实并非如此。
jQueryeach将获取数组的副本并对其进行迭代,因此即使元素已从原始数组中删除,我仍将从 0 到(复制的)数组中的最后一个索引。
但它仍然会出错,因为它splice作用于原始数组,它将元素移动到该数组中的前面的索引。但另一方面,isplice不断增加,因此二分之一的元素将在 中幸存下来。
可以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);
});
});
Run Code Online (Sandbox Code Playgroud)
...但实际上,可以这样简单地完成:
$.xhrPool.abortAll = function () {
$(this).each(function (i, jqXHR) {
jqXHR.abort();
});
$.xhrPool.length = 0;
});
Run Code Online (Sandbox Code Playgroud)