为什么JavaScript不支持多线程?

Niy*_*yaz 255 javascript browser multithreading

这是一个刻意的设计决定还是我们当前浏览器的问题,将在未来版本中得到纠正?

Kam*_*oij 183

JavaScript不支持多线程,因为浏览器中的JavaScript解释器是单线程(AFAIK).即使谷歌Chrome也不会让单个网页的JavaScript同时运行,因为这会在现有网页中造成大量并发问题.所有Chrome确实将单独的多个组件(不同的选项卡,插件等)分离到单独的进程中,但我无法想象单个页面具有多个JavaScript线程.

但是,您可以按照建议使用setTimeout某种调度和"假"并发.这会导致浏览器重新获得对渲染线程的控制,并setTimeout在给定的毫秒数后启动提供的JavaScript代码.如果要在对其执行操作时允许视口(您看到的内容)进行刷新,这非常有用.只需循环遍历例如坐标并相应地更新元素,就可以让您看到开始和结束位置,而不会介于两者之间.

我们在JavaScript中使用抽象库,允许我们创建由同一JavaScript解释器管理的进程和线程.这允许我们以下列方式运行操作:

  • 进程A,线程1
  • 进程A,线程2
  • 进程B,线程1
  • 进程A,线程3
  • 进程A,线程4
  • 进程B,线程2
  • 暂停流程A.
  • 进程B,线程3
  • 进程B,线程4
  • 过程B,线程5
  • 开始流程A.
  • 进程A,线程5

这允许某种形式的调度和伪造并行,线程的启动和停止等,但它不是真正的多线程.我不认为它会在语言本身中实现,因为真正的多线程只有在浏览器可以运行单个页面多线程(甚至多个核心)时才有用,并且存在更大的困难比额外的可能性.

对于JavaScript的未来,请查看:https: //developer.mozilla.org/presentations/xtech2006/javascript/

  • 我认为*从未实施过*视野过于狭隘.我保证网络应用程序最终能够成为真正的多线程(这是合乎逻辑的,因为Web应用程序变得更占优势,硬件变得更加平行),而且正如我所看到的,因为JavaScript是Web开发的事实上的语言,它最终将不得不支持多线程或被某些东西取代. (69认同)
  • 从来没有可能是一个太大胆的声明:)但我仍然认为真正的多线程JavaScript的优势在可预见的未来是不可行的;) (6认同)
  • 虽然我认为Web工作者通过流程模型而不是线程模型更多并发.Web工作者使用消息传递作为通信手段,这是多线程应用程序中"常见"并发问题的优雅解决方案.我不确定他们是否可以同时在与主页面相同的对象上操作.据我所知,他们无法访问DOM.其中大部分都是语义学,网络工作者看起来很有希望实现所有意图和目的. (5认同)

Sho*_*og9 22

传统上,JS旨在用于简短,快速运行的代码片段.如果您正在进行重大计算,那么您是在服务器上进行的 - 在浏览器中长时间运行的JS + HTML 应用程序的想法是非常荒谬的.

当然,现在我们有了.但是,浏览器需要花费一些时间才能赶上 - 大多数都是围绕单线程模型设计的,改变这一点并不容易.Google Gears通过要求后台执行被隔离来解决许多潜在问题 - 不更改DOM(因为这不是线程安全的),不访问主线程创建的对象(同上).虽然限制性,但这可能是不久的将来最实用的设计,因为它简化了浏览器的设计,并且因为它降低了允许没有经验的JS编码人员乱用线程所涉及的风险......

@marcio:

为什么这不是在Javascript中实现多线程的原因?程序员可以使用他们拥有的工具做任何他们想做的事情.

那么,我们不要给他们那些容易被滥用的工具,以至于我打开的每个其他网站都会崩溃我的浏览器.这种天真的实现会让你直接进入导致MS在IE7开发过程中出现如此多头痛的领域:附加作者使用线程模型快速而松散地运行,导致隐藏的错误在主线程上对象生命周期发生变化时变得明显.坏.如果您正在为IE编写多线程ActiveX加载项,我想它是随着领域而来的; 并不意味着它需要更进一步.

  • "它降低了所涉及的风险>允许没有经验的JS编码人员>搞乱线程"为什么这不是在Javascript中实现多线程的原因?程序员可以使用他们拥有的工具做任何他们想做的事情.如果它的好坏,那就是他们的问题.使用Google Chrome流程模型,它甚至不会影响其他应用程序.:) (6认同)
  • @ Shog9 - "让我们不要给那些容易被滥用的[程序员]工具,以至于我打开的每个其他网站都会崩溃我的浏览器." - 什么?按照同样的逻辑,任何语言都不应该有多线程,因为如果他们提出你尝试打开的每个其他程序都会崩溃.除非它不起作用.线程存在于大多数语言中,并且大多数新手程序员都不会触及它,并且大多数不会将其投入生产,以及那些从未变得流行或广泛使用的应用程序. (3认同)

Nei*_*eil 21

JavaScript多线程(有一些限制)就在这里.谷歌为Gears实施了工作人员,HTML5中包含了工作人员.大多数浏览器已经添加了对此功能的支持.

数据的线程安全性得到保证,因为与工作者之间传递的所有数据都是序列化/复制的.

有关详细信息,请阅读:

http://www.whatwg.org/specs/web-workers/current-work/

http://ejohn.org/blog/web-workers/

  • 但这不是更多的多进程方法而不是多线程吗?已知线程在单个堆中工作. (6认同)
  • @beefather,确实如此。它更多的是一种过程方法。 (2认同)

pka*_*ing 10

我不知道这个决定的基本原理,但我知道您可以使用setTimeout模拟多线程编程的一些好处.您可以同时给出多个进程执行操作的错觉,但实际上,所有操作都发生在一个线程中.

让你的函数做一些工作,然后调用类似的东西:

setTimeout(function () {
    ... do the rest of the work...
}, 0);
Run Code Online (Sandbox Code Playgroud)

当他们有机会时,任何其他需要做的事情(如UI更新,动画图像等)都会发生.


Wil*_*ilk 8

Node.js 10.5+ 支持工作线程作为实验功能(您可以在启用--experimental-worker标志的情况下使用它):https : //nodejs.org/api/worker_threads.html

所以,规则是:

  • 如果你需要做I/O 绑定操作,那么使用内部机制(又名回调/承诺/异步等待)
  • 如果您需要执行CPU 绑定操作,请使用工作线程。

工作线程旨在成为长期存在的线程,这意味着您生成一个后台线程,然后通过消息传递与它进行通信。

否则,如果您需要使用匿名函数执行繁重的 CPU 负载,那么您可以使用https://github.com/wilk/microjob,这是一个围绕工作线程构建的小型库。


mat*_*t b 7

你的意思是为什么语言不支持多线程或为什么浏览器中的JavaScript引擎不支持多线程?

第一个问题的答案是浏览器中的JavaScript意味着在沙箱中运行,并且以机器/ OS独立的方式运行,添加多线程支持会使语言复杂化并使语言与操作系统过于紧密地联系起来.


Gre*_*her 6

正如亚光b所说,问题不是很清楚.假设您询问该语言中的多线程支持:因为目前在浏览器中运行的应用程序不需要99.999%.如果你真的需要它,有一些解决方法(比如使用window.setTimeout).

一般来说,多线程是非常,非常,非常,非常非常难(我说它很难吗?)要正确,除非你加入额外的限制(比如只使用不可变数据).