没有工人的Javascript长循环

时间:2015-04-15 13:05:41

标签: javascript infinite-loop web-worker

我需要一个很长的循环(如果我天真地使用它,就足以使浏览器挂起)。这个循环的内容需要其他javascript文件/库,我不喜欢将它们全部连接到一个文件中的想法,因为这会使它更难维护。所以(据我所知)这排除了网络工作者,还有其他解决方案吗?

我需要循环的内容尽可能快地运行,因此任何可以用ms测量的延迟都是不可接受的,任何固定的延迟都不是理想的。

我或许可以在运行时将它们全部连接到一个blob中,然后将其提供给一个Web工作者,我还没有真正研究过它b / c它似乎不是一个好的解决方案。

2 个答案:

答案 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);
}