众所周知,JavaScript在所有现代浏览器实现中都是单线程的,但这是在任何标准中指定的还是只是传统?假设JavaScript总是单线程的,这是完全安全的吗?
当前回答
是的,尽管在使用任何异步api(如setInterval和xmlhttp回调)时仍然会遇到并发编程的一些问题(主要是竞争条件)。
其他回答
JavaScript/ECMAScript被设计为存在于宿主环境中。也就是说,除非宿主环境决定解析和执行给定的脚本,并提供让JavaScript真正有用的环境对象(例如浏览器中的DOM),否则JavaScript实际上什么也不做。
我认为给定的函数或脚本块将逐行执行,这是JavaScript的保证。然而,宿主环境可能同时执行多个脚本。或者,宿主环境可以始终提供一个提供多线程的对象。setTimeout和setInterval是一些例子,或者至少是伪例子,它们说明一个主机环境提供了一种实现并发性的方法(即使它不是真正的并发性)。
Chrome是多进程的,我认为每个进程都有自己的Javascript代码,但就代码所知,它是“单线程”的。
Javascript中不支持多线程,至少不是显式的,所以没有什么区别。
No.
我要跟大家唱反调,但请大家耐心听我说。单个JS脚本的目的是有效的单线程,但这并不意味着它不能被不同的解释。
假设您有以下代码……
var list = [];
for (var i = 0; i < 10000; i++) {
list[i] = i * i;
}
这是在期望到循环结束时,列表必须有10000个索引平方的条目,但VM可能会注意到循环的每次迭代都不影响其他迭代,并使用两个线程重新解释。
第一个线程
for (var i = 0; i < 5000; i++) {
list[i] = i * i;
}
第二个线程
for (var i = 5000; i < 10000; i++) {
list[i] = i * i;
}
这里我简化了,因为JS数组比内存块更复杂,但如果这两个脚本能够以线程安全的方式向数组中添加条目,那么当它们都完成执行时,它将得到与单线程版本相同的结果。
虽然我不知道有哪个VM可以检测这样的可并行代码,但它似乎在将来会出现在JIT VM中,因为它在某些情况下可以提供更快的速度。
进一步应用这个概念,可以对代码进行注释,让VM知道要将哪些代码转换为多线程代码。
// like "use strict" this enables certain features on compatible VMs.
"use parallel";
var list = [];
// This string, which has no effect on incompatible VMs, enables threading on
// this loop.
"parallel for";
for (var i = 0; i < 10000; i++) {
list[i] = i * i;
}
自从Web worker开始使用Javascript,不太可能……更丑陋的系统将会出现,但我认为可以肯定地说Javascript传统上是单线程的。
我的答案是肯定的——因为如果浏览器的javascript引擎异步运行,几乎所有现有的(至少所有非平凡的)javascript代码都会崩溃。
再加上HTML5已经指定了Web Workers(用于多线程javascript代码的显式标准化API),在基本javascript中引入多线程是毫无意义的。
(请其他评论者注意:即使setTimeout/setInterval, http请求onload事件(XHR),和UI事件(点击,聚焦等)提供了一个多线程的粗略印象-他们仍然都是沿着单一的时间轴执行-一次一个-所以即使我们事先不知道他们的执行顺序,也没有必要担心外部条件在事件处理程序,定时函数或XHR回调的执行过程中发生变化。)
是的,尽管Internet Explorer 9会在一个单独的线程上编译你的Javascript,为在主线程上执行做准备。但是,对于作为程序员的您来说,这并没有任何改变。
推荐文章
- 克隆对象没有引用javascript
- 验证字符串是否为正整数
- 如何获得一个键/值JavaScript对象的键
- 什么时候JavaScript是同步的?
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?