我在JS中使用Web Workers存在以下问题。我有一个重型应用程序做一些模拟。代码在多个Web Workers中运行。 主线程正在WebPage上运行。但如果有意义的话,也可能是Web Worker。
示例:
var myWebWorkers = [];
function openWorker(workerCount){
for(var i = 0; i < workerCount; i++){
myWebWorkers[i] = new Worker('worker.js');
myWebWorkers[i].onmessage = function(e){
this.result = e.data;
this.isReady = true;
}
}
}
function setWorkerData(somedata){
// somedata.length is always a multiple of myWebWorkers.length
var elementCntPerWorker = somedata.length / myWebWorkers.length;
myWebWorkers.forEach(function(worker, index){
worker.isReady = false;
worker.postMessage(
somedata.slice(index * elementCntPerWorker,
(index + 1) * elementCntPerWorker - 1));
});
}
var somedata = [...];
openWorker(8);
for(var i = 0; i < 10000; i++){
setWorkerData(somedata);
waitUntilWorkersAreDoneButAllowBrowserToReact(myWebWorkers);
if(x % 100) updateSVGonWebPage
}
function waitUntilWorkersAreDoneButAllowBrowserToReact(){
/* wait for all myWebWorkers-onchange event, but
allow browser to react and don't block a full Web Worker
Following example is my intension. But will not work, because
events are not executed until code excution stops.
*/
somedata = [];
for(var i = 0; i < myWebWorkers.length; i++){
while(!myWebWorkers[i].isReady);
somedata = somedata.concat(myWebWorkers.result);
}
}
我需要的是waitUntilWorkersAreDoneButAllowBrowserToReact
函数或使其运行的概念。每次搜索都是以互斥,睡眠等方式结束,以下句子结束:&#34; JS是单线程&#34;,&#34;这只有在你不在循环中时才有效#34;,&#34;那里没有理由有睡眠功能&#34;。等
即使将主要任务传递给另一名工人,我也遇到了问题,如果其他人准备就绪,这个线程100%负责检查,这是浪费能源和处理能力。
我很想拥有像myWebWorker.waitForReady()这样的阻止功能,这样可以处理事件。这将使javascript更上一层楼。但也许我错过了一个简单的概念,就是这样做。
谢谢!
答案 0 :(得分:3)
我很想拥有像myWebWorker.waitForReady()
这样的阻止功能
不,那是不可能的。您研究的所有语句都是正确的,Web工作者保持异步,并且只能通过消息进行通信。没有等待事件,甚至没有等待工作线程。
你会想要使用promises:
function createWorkers(workerCount, src) {
var workers = new Array(workerCount);
for (var i = 0; i < workerCount; i++) {
workers[i] = new Worker(src);
}
return workers;
}
function doWork(worker, data) {
return new Promise(function(resolve, reject) {
worker.onmessage = resolve;
worker.postMessage(data);
});
}
function doDistributedWork(workers, data) {
// data size is always a multiple of the number of workers
var elementsPerWorker = data.length / workers.length;
return Promise.all(workers.map(function(worker, index) {
var start = index * elementsPerWorker;
return doWork(worker, data.slice(start, start+elementsPerWorker));
}));
}
var myWebWorkers = createWorkers(8, 'worker.js');
var somedata = [...];
function step(i) {
if (i <= 0)
return Promise.resolve("done!");
return doDistributedWork(myWebWorkers, somedata)
.then(function(results) {
if (i % 100)
updateSVGonWebPage();
return step(i-1)
});
}
step(1000).then(console.log);
Promise.all
具有等待并发运行结果的神奇功能,step
函数使用递归方法执行asynchronous looping。