我在JS中执行长计算。在计算过程中,我想显示一个进度条,每个步骤后都会更新。由于正确触发了DOM刷新,我使用setTimeout将步骤排入队列。我自己建立了这样一个函数:
var sequence = function (ar, callback, finalCallback) {
if (ar && ar.length) {
setTimeout(function () {
callback && callback(ar.shift());
sequence(ar, callback, finalCallback);
}, 0);
} else {
finalCallback && finalCallback();
}
};
这几乎与预期一致。正确执行了计算以及我在回调中执行的DOM操作。唯一的问题是,所有的东西都显着缓慢。计算期间的CPU使用率仅为20%。
我的代码有什么问题吗?我想,所有单步都只是入队,并且由于超时为0而没有“真正的”暂停,但是当浏览器不再做任何事情时。
编辑:我尝试在Chrome和Firefox中执行此操作,两者的行为方式相同。 我还尝试将实际的回调调用移到setTimeout之外。没有区别。
根据建议,我尝试使用setInterval代替setTimout,如下所示:
var sequence = function (ar, callback, finalCallback) {
var interval = setInterval(function () {
if (ar && ar.length) {
callback && callback(ar.shift());
} else {
finalCallback && finalCallback();
clearInterval(interval);
}
}, 0);
};
它的行为与setTimeout版本完全相同。
这是一个小提琴,它显示了这些东西:
https://jsfiddle.net/by6oovhz/8/
如果你删除了setTimout,你会看到它实际上有多快(但是DOM不会再被更新)。
答案 0 :(得分:2)
我刚发现了这个问题。 setTimeout行为的原因是,即使您将0作为参数传递,此方法也始终具有较小的超时。在这里,您可以阅读更多相关信息,并找到工作区的链接。它使用window.postMessage创建一个实际上超时为零的函数。
https://developer.mozilla.org/de/docs/Web/API/Window/setTimeout#Minimum_delay_and_timeout_nesting
答案 1 :(得分:0)
我认为你的func已经向窗口发出了一堆超时obj .. 您可以尝试将您的功能更改为此类,以创建TO然后将其删除..
myVar = setTimeout(function(){ mycallback }, 0); // id of timeout
后者在代码中将其删除
clearTimeout(myVar);
或者您可以尝试更改逻辑以使用setInterval吗?
hth,k