Когда последняя часть данных получена, вызовите функцию вычислительно заместитель окончательного решения:
var data = [];
function createWorker(i) {
var v = new Worker('js/worker.js');
v.postMessage(i);
v.onmessage = function(event){
data.push(event.data);
if (data.length === 100) { // <====
computeFinalSolution(); // <====
} // <====
};
}
for(var i = 0; i < 100; i++) {
createWorker(i);
}
Очевидно, параметризуем, что, по вашему мнению, необходимо, но createWorker
в настоящее время не параметрируется, кроме i
, поэтому ...
Обратите внимание, что записи в data
может быть не в порядке. Рабочий для i == 0
может не заполнить до после работника за i == 1
, только из-за капризов планирования потоков или если работа требует большей обработки. Если вам нужны они в порядке, это легко сделать, но мы должны добавить счетчик (или цикл через data
на каждом завершении проверить):
var data = [];
var dataReceived = 0;
function createWorker(i) {
var v = new Worker('js/worker.js');
v.postMessage(i);
v.onmessage = function(event){
data[i] = event.data; // <====
if (++dataReceived === 100) { // <====
computeFinalSolution(); // <====
} // <====
};
}
for(var i = 0; i < 100; i++) {
createWorker(i);
}
Если вы хотите более современный, гибкий подход, рассмотреть вопрос об использовании обещания, которые являются родными для JavaScript от ES2015 (аки ES6) и может быть polyfilled для использования на старых двигателях JavaScript:
function createWorker(i) {
return new Promise(function(resolve) {
var v = new Worker('js/worker.js');
v.postMessage(i);
v.onmessage = function(event){
resolve(event.data);
};
});
}
var promises = [];
for(var i = 0; i < 100; i++) {
promises.push(createWorker(i));
}
Promise.all(promises)
.then(function(data) {
// `data` has the results, compute the final solution
});
Это также имеет то преимущество, что data
будет содержать результаты в порядке, нам не нужно делать эту работу самостоятельно.
Вышеупомянутый раздел соответствует вашему текущему коду, в котором отсутствуют какие-либо положения об ошибках. Но это, как правило, лучше сделать обработку ошибок:
function createWorker(i) {
return new Promise(function(resolve, reject) {
var v = new Worker('js/worker.js');
v.postMessage(i);
v.onmessage = function(event){
// If you report errors via messages, you'd have a branch here for checking
// for an error and either calling `reject` or `resolve` as appropriate.
resolve(event.data);
};
// EITHER:
v.onerror = reject; // Rejects the promise if an error is raised by the web worker, passing along the ErrorEvent
// OR:
v.onerror = function(event) {
// Rejects the promise using the error associated with the ErrorEvent
reject(event.error);
};
});
}
var promises = [];
for(var i = 0; i < 100; i++) {
promises.push(createWorker(i));
}
Promise.all(promises)
.then(function(data) {
// `data` has the results, compute the final solution
})
.catch(function(error) {
// something went wrong
});
@torazaburo: Как делает исходный код. Но я добавлю примечание. –