好的,现在您已经完全简化了问题,这是一个通用数组迭代器函数,它在数组的每个元素的迭代之间设置延迟,并且永远循环,直到回调函数返回false
:
function iterateArrayWithDelay(arr, delay, fn) {
var index = 0;
function next() {
// protect against empty array
if (!arr.length) {
return;
}
// see if we need to wrap the index
if (index >= arr.length) {
index = 0;
}
// call the callback
if (fn(arr[index], arr, index) === false) {
// stop iterating
return;
}
++index;
// schedule next iteration
setTimeout(next, delay);
}
// start the iteration
next();
}
并且,对于您的示例,您将像这样使用它:
iterateArrayWithDelay(s, 1000, myFunction);
你定义的地方myFunction
是处理每个元素的回调函数。回调传递三个项目:
myFunction(item, array, i){
// your code here to process item
}
.delay()
仅适用于使用动画队列的 jQuery 方法。在您的代码示例中,.delay('1000')
没有做任何事情,因为在同一个对象上没有 jQuery 动画方法。
至于内存泄漏,很难跟踪您正在执行的操作的整体上下文,因为我们看不到由 表示的对象的生命周期this
及其属性。这个序列看起来很奇怪:
var x = t.s[i];
...
delete t.s[i];
t.s.push(x);
特别是,我不明白如何delete
语句实际上正在做任何事情,因为您仍然有对内容的引用x
所以什么都不会被垃圾收集。更远,delete
在 javascript 中,用于删除对象属性,而不是用于释放对象或删除数组元素。要释放对象,您必须删除对该对象的所有引用(将它们设置为其他值,以便它们不再包含引用或让它们超出范围)。因此,由于您永远无法摆脱对其中任何内容的引用t.s[i]
,没有任何东西被释放。
您的使用setTimeout()
不会引起递归。你打电话时setTimeout()
,它设置一个计时器并将函数引用放入与该计时器关联的数据结构中。然后,调用函数继续运行并完成执行。因此,它在 setTimeout() 触发并再次调用之前执行完毕。所以,这实际上不是递归。它是一堆连续的函数调用,以时间间隔分隔,并且一个在下一个可以运行之前完成(因为 javascript 是单线程的,并且计时器是为将来设置的)。