1

I require a long loop (long enough to make the browser hang if I used it naively). The contents of this loop requires other javascript files/libraries and I dont like the idea of concatonating them all into one file as this would make it harder to maintain. So (as far as I understand) this rules out web workers, Are there any other solutions out there?

I need the contents of the loop to run as fast as possible so any delay that can be measured in ms is unacceptable, any fixed delay at all would not be ideal.

I might be able to concatonate them all into a blob at runtime and then feed that into a web worker, I havn't really looked into this to far b/c it doesn't seem like a good solution.

7
  • 1
    Use something like browserify to build your Web worker script from modules. Commented Apr 15, 2015 at 13:08
  • have you tried anything so far practically ?? Commented Apr 15, 2015 at 13:08
  • Well at the moment I am running a setInterval(doStuff(), 4); but it is a LOT slower than I would like Commented Apr 15, 2015 at 13:10
  • 3
    You can load other files inside a webworker - it doesn't rule them out. Commented Apr 15, 2015 at 13:18
  • 1
    @jayjay that's a different question, but just this once: importScripts("myscriptfile.js"); Commented Apr 15, 2015 at 13:22

2 Answers 2

1

You will have to use an asynchronous approach for this.

An example is to use a "dispatcher" function which invokes the work for each count and keep tracks of current count. It will make sure the next call is called asynchronous. When done the given callback is invoked.

Example

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
}

Then in the worker function:

function worker(i, callback) {
    // use i for what is needed, then
    callback();                        // will trigger next count
}

And of course, you can do batches instead of invoking a worker function for each count.

For block based approach for more "heavy" data, see also my answer here.

Simple demo below

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>

Sign up to request clarification or add additional context in comments.

Comments

0

Try to wrap loop body into setTimeout with zero time:

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

1 Comment

Your brace in in the wrong place, and this seems to hang the browser for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.