【问题标题】:Terminate a WebWorker (Javascript)终止 WebWorker (Javascript)
【发布时间】:2015-02-15 01:39:15
【问题描述】:

我正在编写一种用于教育目的的语言,它应该在网络浏览器中运行。该语言编译为 JavaScript。

所以存在无限循环和递归的问题。 在那一刻之前,我认为解决方案是将运行时实现为 WebWorker 和 ui 上的按钮,如果运行时间过长则终止它。

我刚刚发现,在测试我的语言时,网络工作者并没有真正被终止,通过调用:runtime.terminate();

至少在他的上一份工作完成之前,我还没有测试过如果完成会发生什么。即使在我到目前为止找到的文档中,它也声明它会立即停止执行。

因此,即使用户可以继续以这种方式工作,后台运行的工作人员也会耗尽资源并至少导致浏览器无响应。

因此,为了响应用户事件,我需要任何方法来终止执行,以防死循环或递归。由于我没有找到任何方法让 JavaScript 中的线程进入睡眠状态,所以这也不起作用,或者网络工作者是否有类似睡眠的方法?

你有什么建议吗?

【问题讨论】:

  • 修复你的无限递归循环。
  • @RobertHarvey,我认为你误解了 OP 想要做什么。他/她正在编写一个编译器。语言的用户会创建无限的递归循环。
  • 是的,你是对的,我正在编写编译器,所以我无法阻止它们,我只是不希望用户最终浏览器挂起......

标签: javascript sleep terminate


【解决方案1】:

我会这样做:

1) 让您的编译器生成代码,而不是从头到尾执行程序,而是将其分解为段 - 例如,循环体或函数体可以是段。

2) 每个段应以timeoutId = setTimeout(nextSegment, 0) 结尾。这允许网络工作者在执行段之间接收和响应异步事件。

3) 当你想终止 web worker 时,使用window.postMessage() 向它发送一条异步消息。

4) 在 Web Worker 内部,有一个事件处理程序,在收到该消息后,它会执行 clearTimeout(timeoutId)

【讨论】:

    【解决方案2】:

    感谢您的回复,我已经考虑过这种方式,所以实际上我不需要网络工作者。 所以这种方法的缺点是:

    1) 我必须将循环实现为递归函数调用...

    还有更大的问题 2) 段大小必须限制为一个命令,这种方法确实有效,所以我必须将每个命令包装到一个调用下一​​个命令的函数中,这将是一个巨大的开销......

    这就是为什么我正在寻找解决方法,如果有的话?

    【讨论】:

    • 开销不应该是明显的,除非您的学生正在编写极其计算密集型的程序。基本问题是这样的:1) 按钮点击只能产生一个事件,2) 与 web worker 通信的唯一方式是通过消息事件,3) web worker 如果持续运行则无法响应事件。定期将控制权返回给浏览器是 Web Worker 可以接收事件并因此被告知它需要停止的唯一方法。
    • 好的,我所做的是依赖 MDN 文档,该文档说 worker.terminate() 将立即终止。我没有建议这立即意味着当处理的事件结束时。我想到了类似 unix kill 之类的进程;-(
    【解决方案3】:

    是的,我正在编写一个编译器。

    我必须提到,在采用这种方法时,用户的开销可能并不多,但对编译的影响确实很大......这就像在 Javascript 之上构建一个 VM......

    到目前为止,除了上述几点之外,我还需要:

    -需要一个复杂的索引系统来命名函数 -照顾变量分配 - 必须解决系列表达式 -...

    这就是为什么我正在寻找更优雅的变体......

    【讨论】:

    • 我不会称之为优雅,但是:来自页面的任何导航(重新加载或跟随链接)都会杀死页面产生的任何网络工作者。因此,如果您不需要原始页面保持不变,您可以让“终止”按钮导致 window.location.reload()。
    • 嗯,这听起来是一个很好的解决方案,我遇到的唯一问题是我的应用程序也应该离线工作,一旦加载,有没有办法在没有服务器访问权限的情况下重新加载?...保存更改我只需要将代码中的更改保存在本地存储中,无论如何我都会这样做......还有另一件事真的会杀死网络工作者吗?所以据我了解终止方法它也应该杀死它,但实际上它是为了友好......
    • 如果您将 Expires HTTP 标头设置为足够远的未来(请参阅developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ),页面应该从缓存中重新加载,即使在离线时也会发生这种情况。是的,重新加载确实会扼杀网络工作者,它们不能超过其父页面。
    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 2020-04-23
    • 2016-10-01
    • 2021-07-12
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多