1

Worker在 javascript 中创建了一个需要无限循环的。在循环内部,它需要进行几次异步调用并等待它们完成,然后再继续。

有两种直接的方法可以做到这一点,我可以看到两者似乎都存在致命缺陷:

1)

while(true) {
  var promise = async_call();
  while(!promise.isResolved()) { }
}

2)

var func = function() {
  var promise = async_call();
  promise.done(func);
}
func();

对于#1,它分崩离析,因为内部while循环可能会消耗大量 CPU;如果线程不可中断,(javascript线程是可中断的吗?我不认为它们是),那么async_call将永远不会真正有机会完成,所以我们只是陷入了一个循环。

对于#2,如果有尾调用优化,它会很好地工作,但我不认为任何 javascript 实现都使用这个,所以它会很快导致堆栈溢出或其他递归限制。

最后,我需要一种方法在两个循环应该终止时向它们发出信号。我可以通过将布尔stop变量放入代码中轻松地做到这一点,但是,这又依赖于工作线程是可中断的,因此我可以设置stop为 true。

是否有我在这里忽略或不熟悉的设计模式?我怎样才能让我的工作人员尽可能快地执行而不诉诸诸如setInterval与轮询配对之类的东西isResolved

4

2 回答 2

3

模式 2 非常好。如果回调真的是异步的(一些 Promise 库强制这样做),它不会以堆栈溢出结束,因为事件将使用全新的堆栈执行。只有当你同步调用 func你会得到溢出,但你只是将它同步注册为回调。

于 2012-12-17T16:39:33.277 回答
0

假设async_call是 XHR 请求或setTimeout回调,您不会溢出堆栈。在新堆栈上调用事件回调(例如 XHR 完成);这不是真正的递归。

至于信号工人停止,使用消息传递。

var worker = new Worker('worker.js');
// when you need to stop it:
worker.postMessage('stop');

worker.js

onmessage = function(e) {
    if (e.data == 'stop') {
        // stop
    }
}
于 2012-12-17T16:39:01.600 回答