Как создать / отправить сообщение веб-воркерам в массиве

Вопрос простой:

Пример:

For (iterate based on amount of cores){
   Let worker = workers[I]
   Worker.postmessage
}

Конец примера.

Заявление об ограничении ответственности: этот пример показывает только то, что ожидается от конечного результата, и ни в коем случае не находится в том, что считается «рабочим состоянием». Также обратите внимание, что использованный выше метод не возвращает worker для «worker [iterator]», а просто undefined.

Задача: Создать методы работы:

1: сделать массив неизвестного количества рабочих (на основе ядер).

2: как только этот массив будет построен, отправьте сообщение каждому работнику и получите результат (отличный от undefined).

Примечание: у меня есть гипотеза, почему это не работает:

1: веб-воркеры создаются и доступны только через событие, которое их создало, и его единственный прием - обработчик «события» onmessage.

  • вопреки моей гипотезе, есть такие вещи, которые могут сказать что-то вроде того, что написано выше, например, thread.js, который позволяет объединять потоки и другие процедуры.

Это основная причина, по которой я спрашиваю, потому что я знаю, что это возможно, но хотел бы получить простой ответ.

Спасибо за ваше время .


person static660    schedule 05.05.2018    source источник


Ответы (2)


Вот пример:

function createWorker (workerScript) {
    const blob = new Blob([`(${workerScript})(self)`], {type: 'application/javascript'});
    return new Worker(URL.createObjectURL(blob));
};

function workerCode (self) {
    self.onmessage = function (message) {
        postMessage(`Data from worker: ${message.data}`);
    };
};

// assuming that you will send only one message to the worker,
// and that the worker will produce only one message too.
function workerPromise (worker, message) {
    const promise = new Promise((resolve, reject) => {
        worker.onmessage = resolve;
    }).then(message => message.data);
    worker.postMessage(message);
    return promise;
}

(async () => {
    const workers = [];
    for (let i = 0; i < navigator.hardwareConcurrency; i++) {
        workers.push(createWorker(workerCode));
    }

    const results = await Promise.all(
        workers.map((w, index) => workerPromise(w, `worker ${index}`))
    );

    console.log(results);
})();
person Thiago Barcala    schedule 05.05.2018
comment
как мне отправить несколько сообщений? Есть ли способ просто использовать вашу функцию createWorker и построить массив с помощью цикла for ?. Мне просто нужен способ управлять бесчисленным множеством рабочих после их создания. - person static660; 05.05.2018
comment
Я также не имею ни малейшего представления о том, как ваш код вообще должен работать, или доказательства того, что он вообще работает, но понимаю, что вы, вероятно, не опубликовали бы его, если бы он этого не сделал. просто хотел бы рабочий пример, чтобы я не думаю, что я отмечаю это как ответ, пока не отобразится рабочий пример (для меня и других, которые просматривают для простоты) - person static660; 06.05.2018

Начните с раздела «Примеры» в разделе: https://developer.mozilla.org/en-US/docs/Web/API/NavigatorConcurrentHardware/hardwareConcurrency.

Измененный пример:

// in Main thread
const numberOfCPUCores = window.navigator.hardwareConcurrency;
const workerList = [];

const cpuWorkerMessageHandler = event => {
  // process message from a worker by accessing: event.data
}

for (let i = 0; i < numberOfCPUCores; i++) {
  const newWorker = new Worker('cpuworker.js');
  newWorker.addEventListener("message", cpuWorkerMessageHandler);
  workerList.push(newWorker);
}

// then, when done with all processing, terminate all workers
workerList.forEach(w => w.terminate());
person Daniel Michalski    schedule 19.05.2020