【发布时间】:2016-04-26 08:06:18
【问题描述】:
我有一个专用的 Webworker,它在接收到启动信号后进入一个长循环,并且根据一些启动设置,循环将在给定的执行点“屈服”。
这是我的代码的简化版本
var mode = null;
var generator = null;
function* loop() {
for(var i=0;i<10000;i++) {
//Do stuff
for(var j=0;j<10000;j++) {
//Do stuff
if( mode == 'inner' ){
//Yield after each inner loop iteration
yield 2;
}
}
if( mode == 'outer' ){
//Yield after each outer loop iteration
yield 1;
}
}
/*
If mode is not inner or outer the function won't yield
and will process the whole loop in one shot
*/
return null;
}
generator = loop();
self.onmessage = function(event) {
var m = event.data;
if(m.operation == 'run') {
mode = m.mode;
generator.next();
}
if(m.operation == 'pause') {
//Set a flag and check for it in the loop
}
}
我想要做的是允许工作人员按需暂停,问题是在循环中工作人员不会处理消息并且不会调用 onmessage 所以我无法发送“暂停”消息设置一个标志,然后我在循环中检查该标志。
我想做的是让我的函数在每次迭代后让出,以允许工作线程处理消息队列,然后如果没有收到暂停信号,则再次恢复函数,但是,这感觉有点 hacky。
有没有办法强制 WebWorker 在不离开循环或屈服的情况下处理消息队列?或者可能是一种无需通过 onmessage() 即可设置标志的方法?
谢谢
【问题讨论】:
-
不,你必须做其中之一 - 离开循环或让出 - 除非 JS 事件循环的核心发生了真正基本的变化。 Javascript 在一个上下文中没有多线程,因此您的循环和
onmessage不可能同时执行。如果您的平台支持yield,我建议您使用它而不是终止循环。 -
我在想一个类似于 C# 中的 DoEvents 的函数,它可以让我让 Javascript 处理队列,这不需要多线程
-
不,您不能从代码中调用队列。实际上,如果您考虑一下,那将是一个递归-从事件循环中调用事件循环。
标签: javascript ecmascript-6 yield web-worker