如何在10次迭代后放入setTimeout?

时间:2012-12-18 13:23:13

标签: javascript jquery

我有一个如下所示的循环

$('#goldBarList tr:not(:eq(0))').filter(':has(:checkbox:checked)').each(function() {  
    $(this).remove();  
});

因为我有4000行,每行都有一个复选框。我需要删除那些选中复选框的行 但是,浏览器停止运行此脚本错误?
因为这个循环需要更多时间才能完成 所以我只想在10次迭代后使用setTimeout并在0.5秒后继续循环。
意味着我希望循环在每10次迭代后休眠1/2秒。 请给我一些代码参考......

...谢谢

4 个答案:

答案 0 :(得分:1)

在重新阅读你的问题后,我意识到我完全误解了你。

这是我修改过的函数,允许您一次只处理数组的一小部分“块”。但是,如果DOM重排导致您头疼,请尝试使用文档片段首先构建树。

修订答案:

function _each(arr, fn/*callback(elem,i)*/, limit/*items per pass*/) {
    limit = limit || 10;
    var count = 0,
        len = arr.length;

    function run() {
        var d = limit;
        while (d-- && len >= count) {
            fn(arr[count], count++);
        }
        if (len > count) setTimeout(run, 1000); // one second is just to show you it working.
    }
    run();
}

Demo here

在回答这个问题之后,我看到了扩展方法以接受完整回调的一些价值。

http://jsfiddle.net/rlemon/hAUcX/7/less readable but smaller version)这是一个带有修订功能的演示。当将超时从0更改为1毫秒时,我注意到了相当明显的性能差异。

答案 1 :(得分:1)

你真正想要的是能够在没有浏览器超时的情况下删除这些元素。即使超时为0,使用window.setTimeout拆分调用也可以解决问题。下面的代码分批执行500次。

编辑:已更新,以提高效果。 (谢谢Bergi。)

var removeTds = function($el) {
    var elements = $el.filter(":lt(500)"),
        count = elements.length;

    elements.remove();
    $el = $el.filter(":gt(499)");
    if (count === 500) {
        window.setTimeout(function() {
            removeTds($el);
        }, 0);
    }
};

removeTds($('tbody tr:not(:eq(0))').filter(':has(:checkbox:checked)'));

这是fiddle

答案 2 :(得分:0)

使用.eachreturn

中的参数引用
$(...).each(function(i,e){
  if (i >= 10) return; // dtop after 10 iterations
  // original code
})

您还可以使用.slice()仅选择10个项目,然后转到.each

$(...).slice(0,10).each(function(){
  // original code
});

如果您想在群组中执行此操作,.slice()也会让您更轻松,因为您基本上可以啜选n元素并抓取m元素(然后处理该群组)。

答案 3 :(得分:0)

您可以使用计数器然后使用break语句

在10次迭代后中断循环
var i = 0; 
$('#goldBarList tr:not(:eq(0))').filter(':has(:checkbox:checked)').each(function() {  
   if(i >= 10)
   {  
       break;
   }
   else
   {
       $(this).remove();
       i++;
   }

});