我需要一个很长的循环(如果我天真地使用它,就足以使浏览器挂起)。这个循环的内容需要其他javascript文件/库,我不喜欢将它们全部连接到一个文件中的想法,因为这会使它更难维护。所以(据我所知)这排除了网络工作者,还有其他解决方案吗?
我需要循环的内容尽可能快地运行,因此任何可以用ms测量的延迟都是不可接受的,任何固定的延迟都不是理想的。
我或许可以在运行时将它们全部连接到一个blob中,然后将其提供给一个Web工作者,我还没有真正研究过它b / c它似乎不是一个好的解决方案。
答案 0 :(得分:1)
您必须使用异步方法。
一个例子是使用“调度程序”函数,该函数调用每个计数的工作并保持当前计数的轨迹。它将确保下一个调用被称为异步。完成后,将调用给定的回调。
示例强>
function startLoop(lFrom, lTo, workFunc, callback) {
var i = lFrom - 1;
(function loop() {
if (++i <= lTo) {
setTimeout(function() {
workFunc(i, loop); // start worker for this count
}, 9); // 9ms delay here - tweak as needed
}
else callback(); // done
})(); // self-invokes loop
}
然后在worker函数中:
function worker(i, callback) {
// use i for what is needed, then
callback(); // will trigger next count
}
当然,您可以进行批量处理,而不是为每个计数调用一个辅助函数。
对于更多“重”数据的基于块的方法,另请参阅 my answer here 。
startLoop(0, 20, worker, function() {alert("done")});
function startLoop(lFrom, lTo, workFunc, callback) {
var i = lFrom - 1;
(function loop() {
if (++i <= lTo) {
setTimeout(function() {
workFunc(i, loop); // start worker for this count
}, 9); // 9ms delay here - tweak as needed
}
else callback(); // done
})(); // self-invokes loop
}
function worker(i, callback) {
// use i for what is needed, then
document.querySelector("div").innerHTML += (i + "...");
callback(); // will trigger next count
}
<div></div>
答案 1 :(得分:0)
尝试用零时间将循环体包装到setTimeout中:
while (some_condition) {
setTimeout(function(){
// ... place your code here
}, 0);
}