这是故意设计的决定还是我们当前的浏览器存在问题,将在未来版本中纠正?
这是故意设计的决定还是我们当前的浏览器存在问题,将在未来版本中纠正?
JavaScript 多线程编程(有一些限制)已经成为现实。Google 对 Gears 实现了 workers,而 HTML5 已经包含了 workers。目前大多数浏览器都已经支持这个特性。
数据的线程安全是得到保障的,因为所有与 worker 通信的数据都被序列化/复制。
欲了解更多信息,请阅读:
传统上,JS仅用于短小、快速运行的代码。如果涉及重要计算,则在服务器上进行操作 - 在浏览器中运行长时间且执行较复杂任务的JS + HTML应用程序是荒谬的想法。
当然,现在我们已经有了这种应用程序。但是,需要花费一些时间让浏览器跟上步伐 - 大多数浏览器都是围绕单线程模型设计的,并且更改它并不容易。Google Gears 通过要求将后台执行隔离来避免许多潜在问题 - 不更改DOM(因为它不支持多线程),不访问主线程创建的对象(同样如此)。虽然有限制,但这很可能是最实用的设计,在不久的将来,这简化了浏览器的设计,也减少了允许缺乏经验的JS编程人员玩弄线程所涉及的风险...
那么,这不是实现JavaScript多线程的原因吗?程序员可以使用他们拥有的工具做任何他们想做的事情。
那么,让我们不要给他们太容易“滥用”的工具,以至于我打开的每个网站都会崩溃我的浏览器。这样的天真实现将使您直接进入导致MS在IE7开发过程中遇到诸多问题的领域:插件作者对线程模型进行了快速和松散的处理,导致隐藏的错误在对象生命周期发生变化时变得明显。这是坏事。如果您正在为IE编写多线程ActiveX插件,则认为它是随之而来的;这并不意味着它需要走得更远。
我不知道这个决定的理由,但是我知道你可以使用setTimeout模拟一些多线程编程的好处。你可以产生多个进程同时做事的错觉,尽管在现实中,所有的操作都发生在一个线程中。
只需要让你的函数做一点工作,然后调用类似下面的内容:
setTimeout(function () {
... do the rest of the work...
}, 0);
当有机会时,会执行任何其他需要完成的任务(例如UI更新、动画图像等)。
setTimeout
内部使用一个loop
,但显然这样做不起作用。你有没有做过类似的事情或者有什么技巧?例如,对于一个包含1000个元素的数组,我希望在两个setTimeout
调用中使用两个for循环,第一个循环遍历并打印元素0..499
,第二个循环遍历并打印元素500..999
。 - benjaminz你是指为什么语言本身不支持多线程还是为什么浏览器中的JavaScript引擎不支持多线程?
第一个问题的答案是,在浏览器中运行的JavaScript被设计成在沙盒环境中以及与机器/操作系统无关的方式运行,添加多线程支持会使语言变得复杂,并将语言与操作系统联系得太紧密。
Node.js 10.5+支持工作线程作为实验性功能(您可以启用--experimental-worker标志使用):https://nodejs.org/api/worker_threads.html
因此,规则是:
工作线程旨在成为长期运行的线程,这意味着您会生成一个后台线程,然后通过消息传递与其通信。
否则,如果需要使用匿名函数执行大量CPU负载,则可以使用https://github.com/wilk/microjob,这是围绕工作线程构建的微小库。
正如matt b所说,这个问题并不是很清楚。假设你在询问语言中的多线程支持:因为目前在浏览器中运行的应用程序中99.999%都不需要它。如果你真的需要它,有一些变通方法(比如使用window.setTimeout)。
总的来说,多线程非常非常非常困难(我说过它很难吗?),除非你加入额外的限制(比如仅使用不可变数据)。
目前一些浏览器支持多线程。因此,如果您需要使用多线程,可以使用特定的库。例如,请查看以下材料:
Javascript是一种单线程语言。这意味着它只有一个调用堆栈和一个内存堆。正如预期的那样,它按顺序执行代码,并在移动到下一个代码片段之前必须完成执行。它是同步的,但有时可能会有害。例如,如果一个函数需要花费很长时间才能执行或者必须等待某些东西,那么在此期间它会冻结所有操作。