等待一组工人完成

时间:2017-06-29 15:37:50

标签: javascript multithreading web-worker

我有一组名为workers的网络工作者。我在一个名为activate的函数中启动它们。问题是,我希望activate返回worker发布的值。我要么希望它返回某种承诺,要么等到它们全部完成。

所以代码可以是:

// 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;
}

所以我可以这样使用它:

var values = await activate();

一旦最后一个工人完成,我不希望工人调用单独的功能。有什么方法可以实现这个目标吗?

2 个答案:

答案 0 :(得分:2)

你想要做的是创建Promise,并在Promise函数内部启动所有worker,并检查最后一次调用promise的resolve函数,并在你的activate函数中返回这个promise

会是这样的:

// 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;
}

该代码目前尚未经过测试,但希望您明白这一点。

答案 1 :(得分:2)

这样做的一种方法是将所有内容包装在一个承诺中,

  const workers = [ new Worker("./worker1.js"), new Worker("./worker2.js")];

  const activate = () => {

      return new Promise((resolve,reject) => {
          let result = [];
          for ( let i = 0 ; i < workers.length; i++) {
             workers[i].postMessage("do something");
             workers[i].onmessage = function(e) {
                result.push(e.data);
             };
          }
          resolve(result)
       });
    };

   async function f() {
     let res = await activate();
     console.log(res);
   }
   f();