В ожидании набора рабочих, чтобы закончить

У меня есть множество веб-работников, называемых 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 ответа

Решение

То, что вы хотите сделать, - это создать Обещание, а внутри функции Обещания инициировать всех рабочих и проверить, когда наступит последний из них, вызвать функцию разрешения обещания и вернуть это обещание в вашу функцию активации.

Было бы что-то вроде этого:

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

Код пока не тестировался, но надеюсь, вы поняли идею.

Один из способов сделать это - завернуть все в обещание,

  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();
Другие вопросы по тегам