繁体   English   中英

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

[英]How to stop long javascript loops from crashing the browser?

我的页面中有一个按钮,循环播放一系列DIV并对其进行编辑(主要是附加文本,没有什么严重的),事实是,用户可以更改DIV的数量(用户可以自由添加或删除它们),

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

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

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

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

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

谢谢

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

.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) {
    ..

添加一个定时器,它将每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

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

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


    console.log("CRASH");

}

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

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

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

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

您可以对任务进行排队,然后每隔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例如不多大意义在这里...

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM