Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web workers #112

Open
xwchris opened this issue Sep 3, 2020 · 0 comments
Open

Web workers #112

xwchris opened this issue Sep 3, 2020 · 0 comments

Comments

@xwchris
Copy link
Owner

xwchris commented Sep 3, 2020

Web Workers允许Web应用程序在一个与主线程分离的后台线程中运行脚本。这样的好处是,可以让一些费时的任务在worker中处理而不阻塞/放慢主线程。该文参考MDN Web Worker

Web Workers

可以使用Worker函数来创建一个worker对象,它接收一个js文件路径,该js文件中包括了要在worker中执行的代码。

在worker中,全局上下文不是window,而是一个DedicatedWorkerGlobalScope对象

// 创建worker
const worker = new Worker('test.js');

worker和主线程以及其他worker之间可以使用postMessage方法进行通信。使用onmessage来监听接收的消息。

main.js
if (window.Worker) {
	const worker = new Worker('worker.js');
	worker.postMessage({ name: 'xxx' });
}
worker.js
this.onmessage = function (e) {
	console.log(e.data);
}

// output: {name: 'xxx'}

除了该标准worker,还有其他特殊的worker,以下部分都是介绍这些特殊的worker。

Shared Workers

不同于上面介绍的专用worker,shared workers可以在多个浏览上下文中共享,如多个页面、多个worker之间共享。它的全局对象是SharedWorkerGlobalScope的实例。

与专用worker不同,shared worker需要通过其返回的MessagePort的对象进行通信和控制。获取该对象需要使用port属性。

如果使用addEventListener进行了事件绑定,需要使用port.start()方法进行激活。

shared worker代码内部,需要使用onconnect事件来监听连接事件。

index.js
var worker = new SharedWorker("worker.js");
worker.port.addEventListener("message", function(e) {
		console.log("Got message: " + e.data);
}, false);
worker.port.start();
worker.port.postMessage("start");
worker.js
var connections = 0;

self.addEventListener("connect", function(e) {
    var port = e.ports[0];
    connections ++;
    port.addEventListener("message", function(e) {
        if (e.data === "start") {
            var ws = new WebSocket("ws://localhost:6080");
            port.postMessage("started connection: " + connections);
        }
    }, false);
    port.start();
}, false);

Service Workers

service worker有着自己独特的功能,虽然它也是一个worker。引用MDN上对Service Worker的介绍,它能够拦截网络请求,本质上充当Web应用程序和浏览器之间的代理服务器,也可以在网络可用时作为浏览器和网络间的代理。目的是为了能够在浏览器上创建有效的离线体验。此外,他们还允许访问推送通知和后台同步API。

出于安全考量,Service Worker只能由HTTPS承载,毕竟修改网络请求能力暴露给中间人会非常危险。Service Worker能细致的控制每一件事情。它被设计为完全异步,同步API(如果XHR和localStorage)不能再service worker中使用。

Service Worker生效的步骤是:注册 -> 安装 -> 激活。激活后的service worker就可以托管web app了。

其他Workers

其他特殊的workers还包括Chrome WorkersAudio Workers,由于它们的常用性和兼容性,这里不再介绍。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant