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.
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
});
}