title: 初探Web Workers date: 2021-06-09 23:55:00 updated: 2021-06-09 23:55:00 photos:
Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface.[1]
简单的翻译就是:Web Workers
是一个关于在 web 内容中跑脚本的后台线程的简单方法。工作线程可以在不干扰用户界面的同时执行任务。
看完上面的描述后,可以了解到,他可以在 Web 页面中创建线程(或进程,不同浏览器中的 Worker 实现不一样)去执行主程序之外的其他任务。
要使用 webWorker 很简单,首先创建一个worker
实例
new Worker(URL, options);
/**
* 它接受两个参数,分别是:
* URL 表示worker 将执行的脚本的URL。它必须遵守同源策略
* options {
* type: 'classic' | 'module', // 用以指定 worker 类型的 DOMString 值.
* credentials: 'omit' | 'same-origin' | 'include', // 用以指定 worker 凭证的 DOMString 值
* name: string, // 在 DedicatedWorkerGlobalScope 的情况下,用来表示 worker 的 scope 的一个 DOMString 值,主要用于调试目的
* }
*/
webworker 实例提供两个监听器:onmessage
和onerror
。同时他还提供postMessage
方法
onmessage
就是监听到数据传入时触发的方法,onerror
则是用于错误捕捉.
postMessage
用于传输数据到工作线程。
通过这些监听器和方法,可以了解到 worker 的工作流程如下图。
根据时序图可以编写出程序:
// main.js
const worker = new Worker("worker.js");
worker.postMessage("hello");
worker.onmessage = function (e) {
console.log(e.data); // Result: hello
worker.terminate();
};
worker.terminate();
// worker.js
self.onmessage = function (e) {
console.log(e.data); // hello
var workerResult = "Result: " + e.data;
postMessage(workerResult);
};
上述代码就是一个简单的 worker 工作流程。
主线程创建 worker 后,加载 worker.js,worker.js 必须与主页面同源的!!,之后 worker 向线程发送消息。
worker.js 收到消息后,执行应的代码,再执行window.PostMessage
将数据返回到主页面中。
主页面收到信息后触发 onmessage 方法,最后调用terminate
结束工作线程。
自此,主页面与工作线程通信结束
可以注意到,worker
是一个 JS 脚本文件那么可以知道,他的作用域与主页面是独立的,也就是他们不共享作用与,所以 web worker 是无法改变 DOM 的。可以看到,worker 线程与主页面相比功能是有限的。
worker 中的全局提供的全局方法有[2]:
除此之外 worker 中还能引入其他的脚本文件,我们可以调用importScript()
的方法接受一个或多个脚本文件。又是需要注意,引入的脚本不能使用包含页面操作的代码。
上面介绍的 worker 是只能被生成它的父页面所调用,他是被一个主页面所独占的,这样的 worker 就叫做专用worker
除了专用 worker,还有一种工作线程可以被多个主页面所调用,这种 worker 就叫做共享 Worker。
window 提供shareWorker
类来创建共享 Worker
// 传入的参数与专用worker一致
const share = new ShareWorker(URL, options);
/**
* share返回一个port属性
* share.port
* share.port.start() 开放传输的端口
* share.port.end() 关闭传输的端口
* share.port.postMessage() 发送消息,必须先调用share.port.start方法
*/
了解了共享 Worker 后,我们再来写一个例子
// main_1.js 主页面 1
const share = new ShareWorker("worker.js");
share.port.start();
share.port.postMessage("hello");
// 接收消息出发
share.port.onmessage = function (e) {
console.log(e.data); // Result: hello
};
// worker.js
onconnect = function (e) {
const main_1 = e.port[0];
main_1.onmessage = function (e) {
main_1.postMessage(`Result: ${e.data}`);
};
};
本文主要介绍了 web workers 的概念和作用。
若您觉得文章对你有帮助,可以点一个赞鼓励一下作者,若想了解更多 JavaScript 或者 node 知识可以点击这里。