JS中的Web Workers存在以下问题。我有一个重型应用程序在做一些模拟。该代码在多个Web Worker中运行。主线程在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
功能或概念。每次搜索涉及Mutex,sleep等时,都以以下语句结尾:“ JS是单线程的”,“仅当您不在循环中时才起作用”,“没有理由具有睡眠功能”。等等。
即使将主要任务传递给另一个工作人员,我也遇到了问题,即该线程有100%的责任检查其他线程是否准备就绪,这浪费了精力和处理能力。
我希望拥有一个像myWebWorker.waitForReady()这样的阻塞函数,该函数仍可以处理事件。这将把javascript推向新的高度。但也许我错过了一个可以做到这一点的简单概念。
谢谢!
我很想拥有像myWebWorker.waitForReady()这样的阻塞函数
不,那是不可能的。您研究的所有语句都是正确的,Web Worker保持异步状态,并且仅通过消息进行通信。没有等待事件,甚至在工作线程上也没有。
您将需要为此使用诺言:
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
函数使用递归方法进行异步循环。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句