Search code examples
javascriptmultithreadingweb-worker

Waiting for a set of workers to finish


I have an array of webworkers, called workers. I'm initiating them all in a single function, called activate. The problem is, I want to have the activate return the values that are posted by the worker. I either want it to return a promise of some kind or wait until they are all done.

So the code could be:

// the web workers add stuff in this array with onmessage()
var globalArray = [];
function activate(){
  for(var i = 0; i < workers.length; i++){
    workers[i].postMessage('do something');
  }

  return // Promise or filled globalArray;
}

So I could use it like this:

var values = await activate();

I don't want the workers to call a seperate function once the last worker is finished. Is there any way I can achieve this?


Solution

  • What you want to do is to create the Promise, and inside of the function of the Promise, initiate all the workers and check when the last ends to call the resolve function of the promise, and return this promise in your activate function.

    Would be something like this:

    // the web workers add stuff in this array with onmessage()
    var globalArray = [];
    function activate(){
        var promise = new Promise(function(resolve, reject){
            var counter = 0;
            var array = [];
            var callback = function(message){
                counter++;
                //You can add here the values of the messages
                globalArray.push(message.data);
                //Or add them to an array in the function of the Promise
                array.push(message.data);
                //And when all workers ends, resolve the promise
                if(counter >= workers.length){
                    //We resolve the promise with the array of results.
                    resolve(array);
                }
            }
            for(var i = 0; i < workers.length; i++){
                workers[i].onmessage = callback;
                workers[i].postMessage('do something');
            }
        });
        return promise;
    }
    

    The code has not been tested for now, but hope you get the idea.