I am working on a Javascript simulator that runs in a web browser. It has a main loop:
do {
updateVisualization(simulator);
simulator.doStep();
} while (!reachedGoal(simulator));
And for every iteration, I need to run several workers that must be concurrently executed:
doStep = function() {
...
for (every agent in the simulation) {
var worker = new Worker('worker.js');
worker.onmessage = function(event) {
...
}
worker.postMessage(...);
}
// Here is the problem
}
My question is: how could I wait for every worker to finish?
A suggestion:
doStep = function () {
var i, worker;
updateVisualization( simulator );
simulator.workers = []; // array of workers for this step
for ( i = 0; i < agents.length; i++ ) {
// set up new worker
worker = new Worker( 'worker.js' );
worker.onmessage = function ( e ) {
var i;
if ( e.data === 'finished' ) {
this.finished = true;
for ( i = 0; i < simulator.workers.length; i++ ) {
if ( !simulator.workers[i].finished ) {
return;
}
}
// survived for-loop = all workers finished
if ( !reachedGoal( simulator ) ) { // another iteration?
simulator.doStep();
}
}
};
worker.postMessage( 'doStep' );
simulator.workers.push( worker ); // push worker into workers array
}
};
So all the action happens in the onmessage
callback of the workers. Every time a worker responds with a message, you inspect the simulator.workers
array by checking if all workers have a finished
property set to true
. If that is the case, this means that all workers finished and you can move on (the "survived for-loop" part).
So basically, you instantiate all workers and then just wait for their responses... no loop required.