如何阻止长时间的javascript循环崩溃浏览器?

时间:2012-02-10 16:13:25

标签: javascript jquery

我的页面中有一个按钮,循环播放一系列DIV并对其进行编辑(主要是附加文字,没什么大不了的), 问题是,用户正在改变DIV的数量(用户可以自由添加或删除它们),

我通过jQuery $ .each函数循环DIV:

var DomToEdit = $('.divs_to_edit');
$.each(DomToEdit, function() { $(this).append('text'); ... });

变量DomToEdit包含一些无限数量的div,然后我通过$ .each函数引用它们。

有时在执行$ .each循环时,用户会等待几个secons,在更糟糕的情况下,浏览器会崩溃

有没有办法防止这种情况发生?也许50 DIV后循环“睡眠”?

由于

编辑:我没有使用相同的ID,对不起 - 这是我的解释中的一个缺陷。我使用同一个班级。 :)

6 个答案:

答案 0 :(得分:3)

.each处理程序中函数的第一个参数是当前元素的索引。您只需在它之前添加一个检查,然后return false停止循环。

$.each(DomToEdit, function(i) { // or DomToEdit.each(function() {
    if (i === 50) return false;
    ..

DomToEdit是一个jQuery对象,因此$.each(DomToEdit, fn)DomToEdit.each(fn)是等效的。

更有效的方法是使用.slice(0, 50)切断元素。

DomToEdit.slice(0, 50).each( function(i) {
    ..

答案 1 :(得分:2)

添加一个定时器,它将每5秒执行追加50个div并通过div数组工作,直到它完成迭代所有div。

下面的代码每5秒就有50个div。

var DomToEdit = $('#divs_to_edit');
var timer = setInterval( function () { //<-- Create a Timer
   $.each(DomToEdit, function(index) { //<-- Iterate thru divs
       if (index == 50) return;        //<-- Return on 50 for later
       $(this).append('text'); 
   });
   DomToEdit = DomToEdit.slice(0, 50); //<-- Slice the processed div's

   // Clear timer when all elements are processed.
   if (DomToEdit.length == 0) {
      clearInterval(timer);
   }
}, 5000);                              // <-- Do the steps on every 5 secs

答案 2 :(得分:1)

每当我认为代码可能导致崩溃时,我将创建一个自动执行breaker变量,该变量在一定数量的循环周期后突破循环。

var breaker = 100;
while(true) {
    breaker--;if(breaker<0){console.log("Oh snap batman");break;}


    console.log("CRASH");

}

该方法也可以执行可以解决崩溃问题的替代代码。通常,我只是尝试以某种方式修复代码;)

答案 3 :(得分:1)

你可以setTimeout为0,以便将每个元素的处理排队到执行堆栈中(0使它只是没有延迟的队列):

$.each(DomToEdit, function() { 
    var elem = $(this);

    setTimeout(function() { elem.append('text'); }, 0);
});

答案 4 :(得分:1)

您可以对任务进行排队,然后执行任务 每隔Y毫秒批量生产X:

var queue = [];

$.each(DomToEdit, function () {
    queue.push( $.proxy( function () {
        $(this).append('text');
    }, this ));
});

window.setInterval( function(){
    var l = 100;

    while( queue.length && l-- ) { //Keep executing tasks until there
                                   //is no more or maximum amount of tasks
                                   //executed for this batch is executed
        queue.shift()();
    }

}, 50 );

真正的解决方案当然是仔细检查你正在做什么并解决这个问题。 $('#divs_to_edit')总是返回单个元素最大值,因此.each在这里没有多大意义,例如......

答案 5 :(得分:0)

使用极大量的元素是可能的,将整个容器元素作为字符串拉出并在其上运行Javascript .replace()并替换整个容器实际上会减少处理器密集度,而不是循环使用成千上万的元素?