我正在使用发布在以下位置的插件代码:
...这是一个异步定时器循环:
jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
if (!in_array.length) return; // make sure array was sent
var i = 0; // starting index
bgEach(); // call the function
function bgEach()
{
if (in_callback.call(in_array[i], i, in_array[i]) !== false)
{
i++; // move to next item
if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
}
}
return in_array; // returns array
};
jQuery.fn.forEach = function (in_callback, in_optional_pause_ms)
{
if (!in_optional_pause_ms) in_optional_pause_ms = 10; // default
return jQuery.forEach(this, in_optional_pause_ms, in_callback); // run it
};
在这个伟大社区的帮助下,我了解到如果我“回归真实”;或“返回假”;它具有与继续循环的下一次迭代相同的效果。
我想做的还是以编程方式完全杀死(销毁)$ .forEach循环调用,不允许剩余的迭代运行。
如何向此插件添加方法以允许我终止对插件的特定调用,同时不影响同时运行调用的其他调用?
我考虑过将调用分配给变量,如下所示:
var foo = $.forEach(json, 1000, function(idx,item) { /* do stuff */ });
...稍后引用特定实例而不影响其他实例,但如何添加kill方法并在foo上调用它?我需要与ajax调用一起使用的等效foo.abort()。
可以吗?如果是这样,怎么样?
答案 0 :(得分:0)
这只是示例代码,因此它有一些问题。
您可以通过简单地将一个expando属性添加到in_array对象来缓解这种情况:
jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
// Note, you should use $.isArray(), which is smarter than checking length.
if (!$.isArray(in_array)) return false;
in_array.valid = true;
var i = 0; // starting index
function bgEach()
{
if (!in_array.valid) return;
if (in_callback.call(in_array[i], i, in_array[i]) !== false)
{
i++; // move to next item
if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
}
}
// I moved this because you were calling it before it was defined.
bgEach(); // call the function
return in_array; // returns array
};
由于您从方法中获取原始数组对象,因此您可以在完成后将对象的“valid”属性设置为false:
var foo = $.forEach(json, 1000, function(idx,item) { /* do stuff */ });
foo.valid = false;
由于valid
属性取消了setTimeout递归,这将有效地终止循环。
请注意,这种代码有点危险。你会遇到竞争条件和诸如此类的东西,但是当你开始做伪线程时会发生这种情况。 JS中的异步代码。
答案 1 :(得分:-1)
您可以将计时器传递给回调并更改
if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
到
if (i == in_array.length) clearTimeout(timeout);
这将保证它只会循环次数与项目一样多次。
以下是jQuery forEach:
jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
if (!in_array.length) return; // make sure array was sent
var i = 0; // starting index
bgEach(); // call the function
function bgEach(){
var timeout;
if (in_callback.call(in_array[i], i, in_array[i], timeout = setTimeout(bgEach, in_pause_ms)) !== false)
{
i++; // move to next item
// if end of array, stop iterating
if (i == in_array.length) clearTimeout(timeout);
}
}
return in_array; // returns array
};
如果计时器满足某些条件,则可以使用它来清除计时器,从而结束循环。例如:
$.forEach([1,2,3], 1000, function(idx, item, timer) {
if(item == 2) {
clearTimeout(timer);
}
});