这是一个深思熟虑的设计决定还是我们当前浏览器的问题将在未来版本中得到纠正?
为什么 JavaScript 不支持多线程?
JavaScript 不支持多线程,因为浏览器中的 JavaScript 解释器是单线程 (AFAIK)。即使是谷歌浏览器也不会让单个网页的 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/
JavaScript 多线程(有一些限制)就在这里。Google 为 Gears 实现了 worker,并且 worker 被包含在 HTML5 中。大多数浏览器已经添加了对此功能的支持。
数据的线程安全是有保证的,因为所有与 worker 通信的数据都是序列化/复制的。
欲了解更多信息,请阅读:
传统上,JS 旨在用于简短、快速运行的代码段。如果您正在进行重大计算,那么您会在服务器上进行——在您的浏览器中长时间运行的 JS+HTML应用程序的想法是荒谬的。
当然,现在我们有了。但是,浏览器要赶上它需要一点时间——它们中的大多数都是围绕单线程模型设计的,改变它并不容易。Google Gears 通过要求隔离后台执行来回避许多潜在的问题 - 不更改 DOM(因为这不是线程安全的),不访问主线程创建的对象(同上)。虽然有限制,但在不久的将来,这可能是最实用的设计,因为它简化了浏览器的设计,并且因为它降低了允许没有经验的 JS 编码人员乱七八糟线程所涉及的风险......
为什么这是不在 Javascript 中实现多线程的原因?程序员可以使用他们拥有的工具为所欲为。
那么,我们不要给他们提供很容易被滥用的工具,以至于我打开的每个其他网站最终都会使我的浏览器崩溃。一个幼稚的实现会让你直接进入在 IE7 开发过程中导致 MS 如此令人头疼的领域:附加组件作者在线程模型上快速而松散地玩弄,导致隐藏的错误在主线程上的对象生命周期发生变化时变得明显. 坏的。如果您正在为 IE 编写多线程 ActiveX 附加组件,我想它会随附;并不意味着它需要走得更远。
我不知道这个决定的基本原理,但我知道您可以使用 setTimeout 模拟多线程编程的一些好处。您可以产生多个进程同时做事的错觉,但实际上,一切都发生在一个线程中。
只需让您的函数做一些工作,然后调用类似的东西:
setTimeout(function () {
... do the rest of the work...
}, 0);
任何其他需要做的事情(如 UI 更新、动画图像等)都会在他们有机会时发生。
你的意思是为什么语言不支持多线程或者为什么浏览器中的 JavaScript 引擎不支持多线程?
第一个问题的答案是浏览器中的 JavaScript 旨在在沙箱中以独立于机器/操作系统的方式运行,添加多线程支持会使语言复杂化并使语言与操作系统过于紧密地联系在一起。