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


当前回答

Javascript是一种单线程语言。这意味着它有一个调用堆栈和一个内存堆。正如预期的那样,它按顺序执行代码,并且必须在执行下一段代码之前完成。它是同步的,但有时是有害的。例如,如果一个函数需要一段时间才能执行,或者必须等待某项操作,那么它会同时冻结所有内容。

其他回答

Javascript是一种单线程语言。这意味着它有一个调用堆栈和一个内存堆。正如预期的那样,它按顺序执行代码,并且必须在执行下一段代码之前完成。它是同步的,但有时是有害的。例如,如果一个函数需要一段时间才能执行,或者必须等待某项操作,那么它会同时冻结所有内容。

它的实现不支持多线程。目前谷歌Gears提供了一种通过执行外部进程来使用某种形式的并发的方法,但仅此而已。

新的浏览器谷歌应该今天发布(谷歌Chrome)通过在进程中分离一些代码并行执行。

当然,核心语言可以提供与Java相同的支持,但对Erlang并发性之类的支持还远远不够。

据我所知,谷歌Chrome将有多线程javascript,所以这是一个“当前实现”的问题。

如果没有适当的语言支持线程同步,那么新的实现尝试线程同步就没有意义了。现有的复杂JS应用(例如任何使用ExtJS的应用)很可能会意外崩溃,但如果没有同步关键字或类似的东西,也很难甚至不可能编写正确运行的新程序。

Node.js 10.5+支持工作线程作为实验特性(你可以使用——experimental-worker flag enabled): https://nodejs.org/api/worker_threads.html

所以,规则是:

如果你需要做I/O绑定操作,那么使用内部机制(即callback/promise/async-await) 如果你需要做CPU绑定的操作,那么使用工作线程。

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

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