@Diode:在无限循环的情况下, shift && push 是更好的选择。忘了他们。在这种情况下,我建议如下:
var intervalId = setInterval((function(theArray)
{
var target = $('#target');
var current;
return function ()
{
current = theArray.shift();
target.load(current);
theArray.push(current);
};
})($('#target').data('widget-load').split("|")),1000);
尝试这个:
var intervalId = setInterval((function(theArray)
{
var target = $('#target');//only search for this once, not on every call
//to make infinite loop, copy the array
var resetArr = theArray.slice(0);//use slice, if not a reference is assigned and both arrays will be altered
//Name is not required, if you want to use a name, pick a better one, next might be reserved (not sure)
//best go for nextInterval, chose this one for explanation
return function next()
{
//get first element, theArray is now 1 shorter
target.load(theArray.splice(0,1)[0]);
if (theArray.length === 0)
{//no more files left -> this stops the interval
//clearInterval(intervalId);
//intervalId = null;
//restore the array, the loop starts from file1 again --> infinite loop
theArray = resetArr.slice(0);//copy the original value
}
}
})($('#target').data('widget-load').split("|")),1000);
这可能有点密集,但我在 chrome 控制台中尝试了一个简单的单行版本:
foo = setInterval((function(arr){ return function(){alert(arr.splice(0,1)[0]); if (arr.length === 0){ clearInterval(foo);}};})([1,2,3]),1000);
它就像一个魅力。
这个怎么运作:
intervalId
保存间隔的 erm id ......有点参考。只要设置好了,该函数就会被调用 every 1000ms
。我没有传递一个简单的函数作为第一个参数,而是创建了一个函数,并立即调用它。我传递给无名函数 ( theArray
) 的参数可以被调用的函数访问next
,它是匿名函数的返回值。它是在函数内部创建的,因此它可以访问其母函数的所有变量,即使在母函数返回之后也是如此。
这意味着theArray
除了函数之外的其他任何地方的值都超出了范围next
,这是我们间隔的实际回调。没有什么可以干扰的价值theArray
,任何外部代码都不能覆盖任何内容,与使用全局变量相比,这是一种更安全的方法。
这同样适用于变量target
:它是在匿名的母亲函数中声明和初始化的,该函数被调用一次,然后被 GC'ed。该变量仍然存在,并引用了一个 jQuery 对象。DOM 只被搜索过一次,用于该元素,但每次新调用该next
函数都可以访问该对象。这样做一次,速度差异很小,一直这样做,你的脚本会(很多)更有效率!
因此,间隔:每 1000 毫秒,next
被调用一次。theArray
它从作为其创建者(该匿名函数)的参数()的数组中转移第一个值。当该数组为空时,clearInterval
调用该函数以停止该批次。所有文件都已加载,继续进行没有意义。
一旦发生这种情况,theArray
, next
-function 和所有其他变量 ( target
) 就会超出范围,所以没有全局变量,只是一块漂亮、干净的内存,这总是一件好事。我假设此代码将作为事件处理程序的一部分触发,在这种情况下,您只需将其复制粘贴到处理程序中,同样不会创建全局变量。
如果此代码将成为全局范围的一部分,则只需将其全部包装在自调用函数中即可轻松避免全局变量:
(function()
{
var intervalId = setInterval((function(theArray)
{
//...
})($('#target').data('widget-load').split("|")),1000);
})();
你都准备好了。恕我直言,这是解决这个问题的最好、最安全和最有JS 意识的方法。JavaScript 是关于函数的,你越多地利用它们,语言就越喜欢它。事实上,它会通过揭示其隐藏的表现力来感谢你。
即使您决定不使用此答案,也请阅读诸如闭包之类的内容以及如何充分利用函数范围。你很快就会发现自己以一种全新的方式编写代码,保证 :)