Javascript 没有工人的长循环

Javascript long loops without workers

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

我需要循环的内容尽快 运行 所以任何可以以毫秒为单位测量的延迟都是不可接受的,任何固定延迟都不是理想的。

我可能能够在 运行 时间将它们全部连接成一个 blob,然后将其提供给网络工作者,到目前为止我还没有真正研究过这个 b/c 它没有'这似乎不是一个好的解决方案。

尝试用零时间将循环体包装到 setTimeout 中:

while (some_condition) {
    setTimeout(function(){
        // ... place your code here
    }, 0);
}

您将不得不为此使用异步方法。

一个例子是使用“调度程序”函数,它为每个计数调用工作并跟踪当前计数。它将确保下一次调用称为异步调用。完成后调用给定的回调。

例子

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>