[英]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.