Search code examples
javascripthtmlweb-worker

HTML5 Web Worker does not respond to message


Consider the following code:

worker.js

onmessage = function(evt) {
    postMessage({ data: "foo", id: evt.data.id });
};

master.js (embedded in some HTML)

function startWorker(count) {
  var running = count;
  for (var i = 0; i < count; i++) {
    console.log("Creating worker " + i);
    var worker = new Worker("worker.js");
    worker.onmessage = function (event) {
      console.log("Worker #" + event.data.id + " finished");
      worker.terminate();
      running--;
      if (!running) {
        console.log("All worker finished");
      }
    };
    worker.postMessage({ id: i });
  }
}
startWorker(3);

Whenever I execute this in Chrome or Firefox, most times I do only get the following output:

Creating worker 0 Creating worker 1 Creating worker 2 Worker #0 finished Worker #1 finished

worker 2 is missing in the output, it never responds to the message. However, if I retry this for several times, a few times all workers respond to my message.

Do you know what my problem might be? I created a Fiddle to test this behavior.


Solution

  • The issue here is the variable worker and how it's used inside the onmessage function.

    The onmessage function is async, and there's no special scope in for loops, so the worker variable is overwritten on each iteration and can't be used inside the onmessage function, instead we could use this, like this

    for (var i = 0; i < count; i++) {
        log("Creating worker " + i);
        var worker = new Worker(url);
        worker.onmessage = function (event) {
            log("Worker #" + event.data.id + " finished");
            this.terminate(); // "this" will be the correct worker
            running--;
            if (!running) console.log("All worker finished");
        }
        worker.postMessage({
            id: i
        });
    }
    

    FIDDLE