Web Worker
客户端 JavaScript 一个基本的特性就是单线程,浏览器无法同时运行两个事件处理程序。
在 Web Worker 标准中,定义了解决客户端 JavaScript 无法多线程的问题,这里的「Worker」是指执行代码的并行线程。和任何线程 API 一样,Web Worker 包含两个部分,第一个部分是 Worker 对象,该对象是暴露给创建该线程的线程的,第二个部分是 WorkerGlobalScope,这是一个用来表示新创建的 Worker 的全局对象,也是 Worker 线程内部使用的对象。
Worker 对象
要创建一个新的 Worker,需要使用 Worker()
构造函数:
var loader = new Worker("utils/loader.js"); // 这里的引入的URL受同源策略约束
获取到 Worker 对象后就可以通过 postMessage()
方法来传递参数了:
loader.postMessage("file.txt");
可以通过监听 Worker 对象上的 message
事件来接收来自 Worker 的消息:
worker.message = function(e) {
var message = e.data;
console.log("URL contents: " + message);
};
Worker 对支持 addEventListener() 和 removeEventListener() 方法。此外,该对象还有一个 terminate()
方法,用于强制一个 Worker 线程结束运行。
Worker 作用域
在通过 Worker()
构造函数创建一个新 Worker 的时候,指定了包含 JavaScript 代码文件的 URL,该代码会运行在一个全新的 JavaScript 运行环境中,完全和创建 Worker 的脚本隔离开来。WorkerGlobalScope 全局对象表示了这个新的运行环境。
WorkerGlobalScope 对象也有一个 postMessage()
方法和一个 onmessage
事件处理程序属性。
close()
允许将 Worker 自己终止,从效果上来说和 terminate()
方法类似。
WorkerGlobalScope 对象上定义的最有意思的方法是 importScripts()
,Worker 使用此方法来加载任何需要的库代码:
importScripts("collection/Set.js", "collection/Map.js", "utils/base64.js");
importScripts()
是一个同步方法,直到所有脚本都已经载入并运行完成才会返回,在 Worker 中使用阻塞式函数不会导致主线程中的事件循环,也不会阻塞其他 Worker 中并行执行的计算。
WorkerGlobalScope 是 Worker 的全局对象,所以它有所有核心 JavaScript 全局对象拥有的那些属性,此外,还有客户端 Window 对象拥有的一些熟悉:
- self:全局对象对自身的引用
- 计时器方法
- location属性,描述传递给 Worker 构造函数的URL
- navigator属性
- 事件目标方法:addEventListener() 和 removeEventListener()
- onerror 属性
Web Worker 工作原理:通过传入指定 URL 到 Worker()
构造函数创建一个新的 Worker 对象,然后调用 Worker 对象的 postMessage()
方法将消息传递到 Worker 内部,由 WorkerGlobalScope 对象上的 onmessage
监听传入消息并进行处理,处理完成后通过全局 postMessage()
方法将处理结果返回给外部 Worker,由外部 Worker 对象上的 onmessage
事件处理程序进行最终处理。
No Comments