私は JS に関してはかなり新しいものですが、Web Workers API を調査した後、いくつかの基本的なマルチスレッドに挑戦しました。以下の私の試みは、sendWorkUnit() とも呼ばれる次の作業単位を決定するためのロジックを抽象化し、それをワーカーの開始時およびメッセージ ハンドラー中に使用して、ジョブが終了するまで作業を継続できるようにすることです。
このアプローチは合理的だと思いましたが、設計が間違っているのではないかと疑っています。なんで?ジョブが終了したら各ワーカーを閉じていないことにすぐに気付いたので、 sendWorkUni() を次のように変更しようとしました。
function sendWorkUnit(worker) {
if (workCount < testData.length) {
worker.postMessage(testData[workCount++]);
} else {
worker.terminate();
}
}
ただし、この変更を行うと、すべてが爆発し、配列の最初の 4 つの要素しか返されません。説明や指針をいただければ幸いです。
Manager.js
window.onload = function() {
var numWorkers = 5,
workers = [],
testData = ['f', 'o', 'o', 'b', 'a', 'h'],
workCount = 0,
ol = document.querySelector('#output');
//Spawn some workers
for (var i = 0; i < numWorkers; i++) {
var worker = new Worker('worker.js');
worker.addEventListener('message', function(e) {
displayWorkUnit(e);
sendWorkUnit(worker);
}, false);
workers.push(worker);
}
//Start the workers
for (var i = 0, l = workers.length; i < l; i++) {
sendWorkUnit(workers[i]);
}
//Send next unit
function sendWorkUnit(worker) {
if (workCount < testData.length) {
worker.postMessage(testData[workCount++]);
}
}
//Display each worker's output
function displayWorkUnit(e) {
var li = document.createElement('li');
li.innerHTML = e.data;
ol.appendChild(li);
}
}
Worker.js
self.addEventListener('message', function(e) {
postMessage(e.data.toUpperCase());
}, false);