我正在 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 版本完全相同。
这是一个 fiddle ,显示了内容:
https://jsfiddle.net/by6oovhz/8/
如果删除 setTimout,您将看到它实际上应该有多快(但是 DOM 不再更新)。
最佳答案
我刚刚发现了问题。 setTimeout 行为的原因是,即使您传递 0 作为参数,该方法也始终具有较小的超时。您可以在此处阅读有关它的更多信息并找到解决方法的链接。它使用 window.postMessage 创建一个函数,该函数的超时时间实际上为零。
https://developer.mozilla.org/de/docs/Web/API/Window/setTimeout#Minimum_delay_and_timeout_nesting
关于javascript - 递归 setTimeout() 导致 CPU 使用率低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30274290/