【发布时间】:2016-09-01 21:57:38
【问题描述】:
我对 JS 中的 Web Workers 有以下问题。我有一个重型应用程序做一些模拟。代码在多个 Web Worker 中运行。 主线程在网页上运行。但如果有意义的话,也可以是 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 是单线程的”、“这仅在您不在循环中时才有效”、“没有理由拥有睡眠功能”。等等
即使将主要任务传递给另一个 Worker,我也遇到了问题,即这个线程 100% 负责检查其他线程是否准备好,这是浪费能源和处理能力。
我希望有一个像 myWebWorker.waitForReady() 这样的阻塞函数,它允许仍然处理事件。这将使 javascript 更上一层楼。但可能我错过了一个可以做到这一点的简单概念。
谢谢!
【问题讨论】:
-
当所有在
setWorkerData(somedata)呼叫收到消息的工作人员都向主线程响应消息时,您是否尝试呼叫waitUntilWorkersAreDoneButAllowBrowserToReact?也就是当for循环完成调用waitUntilWorkersAreDoneButAllowBrowserToReact?难以准确解释您要完成的任务? -
为什么在问题示例
javascript中没有message事件处理程序? -
@guest271314:我添加了更多代码以便于理解
-
while在for循环内循环冻结浏览器?网络工作者有change事件吗?当所有网络工作者都向主线程发布消息时,您是否尝试调用函数? -
是的,在控制台中尝试
while(true)。上面已更正为 onmessage。
标签: javascript multithreading web-worker