HTML5网络工作者
Web Workers API使异步和自主执行JavaScript文件成为可能。网络工作者本质上是执行JavaScript文件的线程。因此,使用Web Worker,可以在Web应用程序中实现多线程。
创建一个Web Worker
我们可以这样创建一个网络工作者:
var worker = new Worker("http://Hyman.com/worker.js");
作为参数传递给Worker()
的字符串是要执行的JavaScript文件的URL。
与Web Worker进行通信
我们可以使用HTML5 Messaging API与Web工作者进行通信,方法是向Web工作者发布消息并从Web工作者接收消息。这是一个例子:
var worker = new Worker("http://Hyman.com/worker.js"); worker.onmessage = function(event) { alert("Reply: " + event.data); } worker.postMessage("Hello worker!");
首先创建一个"工人"。
其次,在网络工作者上设置" onmessage"事件监听器功能。当工作程序将消息发送回创建它的页面时,将调用此函数。
第三,使用worker.postMessage()
函数将消息发送给网络工作者。
网络工作者可以这样响应:
this.onmessage = function(event) { postMessage("Reply from web worker"); }
此代码是由网络工作者执行的JavaScript文件的一部分。 " this"关键字是对Web Worker实例本身的引用。一个" onmessage"事件监听器功能被添加到网络工作者。这与创建Web Worker的页面所添加的onmessage侦听器不同,即使两者都添加在worker实例上也是如此。网路工作者使用postMessage()
回应讯息。
交换JSON
在网络工作者的第一个实现中,浏览器仅允许将字符串作为消息交换。我们可以使用JSON.stringify()函数对JSON对象进行编码,并使用JSON.parse()函数再次对其进行解码。
但是,最近的实现允许交换值或者可以由结构化克隆算法处理的JSON对象。
Web Worker实施
这是Web Worker的完整实现:
this.onmessage = function(event) { postMessage("Reply from web worker"); } //Implementation of web worker thread code setInterval(function() { runEveryXSeconds() }, 5000); function runEveryXSeconds() { postMessage("Calling back at : " + new Date().getTime()); }
该Web工作程序实现侦听消息,并每隔5秒向启动它的页面发送一条消息。
Web Worker沙箱
Web工作者在一种沙箱中运行,这意味着Web工作者只能有限地访问JavaScript在浏览器中执行时通常可以访问的功能。
Web工作人员无权访问创建Web工作人员的页面的DOM。
以下是网络工作者可以在网络工作者JavaScript中执行的操作的列表:
- 使用
onmessage
事件监听器功能监听消息。 - 通过
postMessage()
函数发送消息。 - 使用XMLHttpRequest发送AJAX请求。
- 使用setTimeout()和sendInterval()函数创建计时器。
- 网络套接字
- Web SQL数据库
- 网络工作者
- 使用importScripts()导入更多脚本
在Web Worker中导入JavaScript
我们可以使用importScripts()函数导入JavaScript文件以供Web工作者使用。这是Web Worker中可用的特殊功能。这是一个例子:
importScripts("myscript.js"); importScripts("script1.js", "script2.js");
我们可以使用importScripts()函数加载一个或者多个脚本,如上例所示。脚本被同步加载,并且一次执行一次。
共享工作人员
普通的Web工作人员只能由创建它的页面访问。如果要在多个页面之间共享网络工作者,则可以使用SharedWorker
。从相同来源(域)加载的所有页面都可以访问" SharedWorker"。
创建一个SharedWorker
我们可以这样创建一个" SharedWorker":
var worker = new SharedWorker("shared-worker.js");
作为参数传递给" SharedWorker"构造函数的字符串是" SharedWorker"将要执行的JavaScript的URL。
所有使用相同的URL作为参数创建" SharedWorker"实例的页面实际上都会在后台获得与同一" SharedWorker"的连接。
连接到SharedWorker
" SharedWorker"具有一个称为端口的概念,引用" SharedWorker"的各个页面可以通过该端口与之通信。该API再次类似于HTML5 Messaging API。
这是一个如何在SharedWorker
的端口上添加消息监听器的例子:
var worker = new SharedWorker("/html5/web-worker-shared.jsp"); worker.port.addEventListener("message", function(event) { alert(event.data); } , false ); worker.port.start();
首先在" SharedWorker"处创建。其次,将消息事件侦听器功能添加到" SharedWorker"的端口。第三,启动端口。如果不启动端口,则无法将消息发送到" SharedWorker"。
发送消息给SharedWorker
一旦启动端口,并且页面正在侦听端口上的消息,就可以使用port.postMessage()函数将消息发送到SharedWorker。这是一个例子:
worker.port.postMessage("First Message");
SharedWorker实施
像普通的Web工作人员一样," SharedWorker"也需要JavaScript文件中的实现。这是一个示例实现:
var ports = [] ; onconnect = function(event) { var port = event.ports[0]; ports.push(port); port.start(); port.addEventListener("message", function(event) { listenForMessage(event, port); } ); } listenForMessage = function (event, port) { port.postMessage("Reply from SharedWorker to: " + event.data); } //Implementation of shared worker thread code setInterval(function() { runEveryXSeconds() }, 5000); function runEveryXSeconds() { for(i = 0; i < ports.length; i++) { ports[i].postMessage("Calling back at : " + new Date().getTime()); } }
该实现首先创建一个数组,用于存储与SharedWorker
连接的所有页面的端口。
其次,定义了一个" onconnect"功能。当页面连接到" SharedWorker"时调用此函数。
onconnect函数首先获取连接页面的端口,将其存储在端口数组中,然后启动该端口。如果不启动端口,则无法接收来自该端口的消息。最后,onconnect
函数将消息侦听器函数添加到端口。注意如何为每个连接的页面创建一个新的匿名函数。这个匿名函数捕获到连接页面的端口,并将其作为参数传递给从匿名函数调用的listenForMessage()
函数。
在onconnect函数定义了事件监听函数listenForMessage()之后,此函数仅通过一条简单消息响应从其接收消息的端口。
" SharedWorker"的最后一部分包含" SharedWorker"具有的自主行为的实现。调用setInterval()函数使runEveryXSeconds()每5秒(5000毫秒)执行一次。
runEveryXSeconds()
简单地迭代所有连接的端口并向它们写入一条消息。更高级的实现可以连接到服务器并获取数据,该数据可以分发到连接到" SharedWorker"的所有页面。