更新(2018-06-21):对于来这里寻找 JavaScript 中的多核编程的人,不一定是浏览器 JavaScript(为此,答案仍然适用):Node.js 现在支持背后的多线程功能标志(--experimental-workers
):发布信息,相关问题。
在我的脑海中写下这个,不保证源代码。请对我放轻松。
据我所知,你不能真正用 JavaScript 在线程中编程。Webworkers 是多道程序的一种形式;然而 JavaScript 本质上是单线程的(基于事件循环)。
webworker 是独立的执行线程,因为它不与启动它的脚本共享任何内容;没有引用脚本的全局对象(通常在浏览器中称为“窗口”),也没有引用任何主脚本的变量,除了发送到线程的数据。
把网络工作者想象成一个小“服务器”,它被问到一个问题并提供一个答案。您只能将字符串发送到该服务器,它只能解析字符串并将其计算的内容发回。
// in the main script, one starts a worker by passing the file name of the
// script containing the worker to the constructor.
var w = new Worker("myworker.js");
// you want to react to the "message" event, if your worker wants to inform
// you of a result. The function typically gets the event as an argument.
w.addEventListener("message",
function (evt) {
// process evt.data, which is the message from the
// worker thread
alert("The answer from the worker is " + evt.data);
});
然后,您可以使用其 postMessage() 方法向该线程发送消息(字符串):
w.postMessage("Hello, this is my message!");
示例工作脚本(“echo”服务器)可以是:
// this is another script file, like "myworker.js"
self.addEventListener("message",
function (evt) {
var data = JSON.parse(evt.data);
/* as an echo server, we send this right back */
self.postMessage(JSON.stringify(data))
})
您发布到该线程的任何内容都将被解码、重新编码并发回。当然,您可以在两者之间进行任何您想做的处理。该工人将保持活跃;你可以调用terminate()
它(在你的主脚本中;那是w.terminate()
)来结束它或调用self.close()
你的工作人员。
总结一下:你可以做的是将你的函数参数压缩成一个 JSON 字符串,该字符串使用postMessage
“在另一端”(在工作人员中)发送、解码和处理。计算结果被发送回您的“主”脚本。
解释为什么这不容易:更多的交互实际上是不可能的,并且这种限制是故意的。因为共享资源(工作程序和主脚本都可见的对象)会同时受到两个线程的干扰,所以您需要管理对该资源的访问(即锁定)以防止竞争条件.
消息传递、无共享的方法并不为人所知,主要是因为大多数其他编程语言(例如 C 和 Java)使用在同一地址空间上运行的线程(而其他,例如 Erlang,则不)。考虑一下:
- 由于相关的死锁/竞争条件复杂性,使用互斥锁(一种互斥机制)编写更大的项目真的很困难。这是可以让成年男人哭泣的东西!
- 与进行消息传递、无共享语义相比,这真的很容易。代码是隔离的;你确切地知道你的工人有什么,你的工人有什么。死锁和竞争条件是不可能实现的!
试试看;它能够做有趣的事情,可能是你想要的。请记住,据我所知,它是否利用多核仍然是实现定义的。
注意。我刚刚获悉,至少有一些实现会为您处理消息的 JSON 编码。
因此,要回答您的问题(以上都是;tl;dr 版本):不,没有网络工作者,您将无法做到这一点。但是除了浏览器支持之外,Web Worker 并没有什么真正的问题,就像 HTML5 一样。