1. Как я могу запустить нескольких веб-работников? Я попробовал такую петлю:
Нет проблем с созданием более одного рабочего, даже если вы не отслеживаете их в массиве. Смотри ниже.
2. Как я могу контролировать, что все закончили свою работу? (Мне нужно повторно собрать массив и поработать с ним позже)
Они могут отправить сообщение вам, когда они будут сделаны, с результатами. Пример ниже.
3. Сколько веб-работников действительно приносит улучшения?
Как долго является частью строки? :-) Ответ будет полностью зависеть от целевой машины, на которой он работает. Многие люди в эти дни имеют четыре или более ядра на своих машинах. Конечно, машина выполняет множество других вещей. Вы должны настроиться на целевую среду.
4. Есть ли какой-либо расширенный учебник, кроме MDN-записи?
Существует не так много «продвинутых» о веб-работников. :-) Я нашел this article было достаточно.
Вот пример работает пять рабочих и наблюдая за ними, чтобы сделать:
Главное окно:
(function() {
var n, worker, running;
display("Starting workers...");
running = 0;
for (n = 0; n < 5; ++n) {
workers = new Worker("worker.js");
workers.onmessage = workerDone;
workers.postMessage({id: n, count: 10000});
++running;
}
function workerDone(e) {
--running;
display("Worker " + e.data.id + " is done, result: " + e.data.sum);
if (running === 0) { // <== There is no race condition here, see below
display("All workers complete");
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
worker.js
:
this.onmessage = function(e) {
var sum, n;
sum = 0;
for (n = 0; n < e.data.count; ++n) {
sum += n;
}
this.postMessage({id: e.data.id, sum: sum});
};
О состоянии гонки, что не существует : Если вы думаете с точки зрения истинного упреждающего потока, то вы можете подумать: я мог бы создать рабочего, приращение running
- 1
, а затем, прежде чем я создаю следующего работника, я могу получить сообщение от первого, что это сделано, декремент running
- 0
, и по ошибке подумайте, что все рабочие были сделаны.
Это не может произойти в среде, в которой работают веб-сотрудники. Несмотря на то, что среда приветствует запуск работника, как только он захочет, и работник вполне может закончить до того, как код, начинающийся с рабочих, будет выполнен is queue вызов функции workerDone
для основной темы JavaScript. Упреждения не существует. И поэтому мы знаем, что все работники были запущены до первого вызова workerDone
. Таким образом, когда running
- 0
, мы знаем, что все они закончены.
Заключительное примечание. В приведенном выше примере я использую onmessage = ...
для подключения обработчиков событий. Естественно, это означает, что у меня может быть только один обработчик событий для объекта, с которым я это делаю. Если вам нужно иметь несколько обработчиков для события message
, используйте addEventListener
. Все браузеры, которые поддерживают веб-работников, поддерживают addEventListener
на них (вам не нужно беспокоиться об IE attachEvent
вещь).
Для # 2: Вы должны были бы использовать 'postMessage' от работника, чтобы отправить обратно сообщение этому родительскому JS, говорящему, что рабочий обработан (и, вероятно, передает результаты) ...поэтому вам нужно добавить слушателя 'onmessage' для каждого Рабочего в цикле. Вы сохранили бы все эти ответы, вероятно, в массиве. Когда количество ответов в массиве совпадает с количеством созданных рабочих, это должно означать, что все сделано ... и вы можете справиться с этим массивом, который вы создали. Это можно сделать «чище», используя концепцию отложенных объектов jQuery. – Ian
«Нельзя клонировать» означает, что то, что вы * передаете * работнику, не может быть клонировано. Чтобы избежать условий гонки, объекты никогда не разделяются между работниками и основной нитью. Объекты должны быть либо скопированы в пространство памяти рабочего, либо (с помощью 'Blob's и типизированных массивов) основной поток может отказаться от пространства памяти для рабочего и потерять ссылку на объект. – apsillers
Хорошо. Читайте об этом, но забыл. Так или иначе. Если я создаю временную переменную в цикле, сохраните массив как строку и передайте эту строку, было бы лучшим решением? Где-то я читал, что я только посылаю Strings рабочим, где-то в другом месте, что я могу передавать переменные? Спасибо вам за ваше объяснение, хотя, помогает мне начать работу! –