// main.js
var myWorker = new Worker('./worker.js');
// worker.js,里面是worker线程运行的任务(执行的计算比较重的代码)
onmessage = function(e) {
console.log('Message received from main script');
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
console.log('Posting message back to main script');
postMessage(workerResult);
}
启动/运行 Web Worker
首先要知道 Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。所以如果本地创建了一个 html 文件和 js 文件,直接在浏览器打开该 html 文件,Web Worker 是无效的,比如我打开的是file:///Users/xxx/Desktop/aaa/aaa.html,内部引入的js包含了上面 Web Worker 相关的 JS 代码,那么控制台会报出一个错误
说实话,我本人接触的第一个Web Workers就是Service Worker,以前有一个项目是给工人在工地上做工时应用,工地也没有网络,或者说信号极差,所以对离线要求也比较高,当时调研过 Service Worker,但是使用起来有点复杂的,再加上当时不满足浏览器的兼容性,所以就使用了另外一种方式indexdb。
背景
为啥突然想学习 Web Worker 了呢,因为我在某金上看到了一篇文章,而那篇文章有个评论说 Web Worker 实现起来很丝滑,我在想是要怎么实现呢,于是就开启了探究 Web Worker 之旅……
阅读 MDN
一般来讲,对于前端领域看到一个陌生又熟悉的词汇,Google之后都可以看到MDN的解释说明,引经据典嘛,来咯:
显然使用 Web Worker 是有好处的,就是可以将任务重的计算在不阻塞主线程的情况下继续运行,实现性能的提升(不过也不宜过度使用,后面会说到)。
Web Worker 可分为 Dedicated Workers、Shared Workers、Service Workers、Chrome Workers以及音频Workers,后面两个我负责的项目中使用场景不多,就不展开了,主要介绍前三个 Web Workers。
Dedicated Workers
定义、使用
Dedicated Workers 使用构造函数
Worker()
创建一个Worker对象,构造函数接受一个 JavaScript文件URL,这个文件包含了将在 worker 线程中运行的代码,具体例子:启动/运行 Web Worker
首先要知道 Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。所以如果本地创建了一个 html 文件和 js 文件,直接在浏览器打开该 html 文件,Web Worker 是无效的,比如我打开的是
file:///Users/xxx/Desktop/aaa/aaa.html
,内部引入的js包含了上面 Web Worker 相关的 JS 代码,那么控制台会报出一个错误所以如果想在本地调试,需要将文件serve起来,我是用的是python命令:
python -m SimpleHTTPServer 8000
。Chrome Debug
代码上实现了 Web Worker,也确实能正常运行,那么我怎么知道worker到底在哪里呢,我的页面里面有几个workers呢?
打开 Chrome -> CMD+SHIFT+I -> Sources Tab -> Page,然后就可以看到有多少个 Web Worker 以及具体 Web Worker 的脚本。
关闭 Web Worker
使用完毕,为了节省系统资源,必须关闭 Worker。
对于 Dedicated Workers而言,关闭意味着在 chrome 的sources tab也会消失:
Shared Workers
Shared Workers 跟 Dedicated Workers使用上是基本一致的,可能更复杂一些,Shared Workers 可被不同的窗体的多个脚本运行,例如IFrames等。代码举例🌰:
在Chrome的debug方式也不一样,打开
chrome://inspect
,可以看到很多navigations,其中有一个叫做Shared Workers
,那这里是可以看到打开的网页有哪些是使用了 Shared Workers的。Service Workers
说实话,我本人接触的第一个Web Workers就是Service Worker,以前有一个项目是给工人在工地上做工时应用,工地也没有网络,或者说信号极差,所以对离线要求也比较高,当时调研过 Service Worker,但是使用起来有点复杂的,再加上当时不满足浏览器的兼容性,所以就使用了另外一种方式
indexdb
。根据文档,Service Worker 可以创建有效的离线体验,拦截网络请求,以及根据网络是否可用采取合适的行动,更新驻留在服务器上的资源。
Angular框架是实现了 Service Worker的,而其中也有一些bug(记得是版本7,现在有可能已经修复了,很久没用过Angular了😅),如果开启了之后,可能会对版本的更新有一定的影响,话说至今我都不明白为啥那个项目要开启Service Worker,大家也米有离线的需求额……
在Chrome浏览器也是可以很方便地debug,在Application tab的子菜单里面:
开发注意的地方/限制
但是还是有很多 Web API 在 Web Workers中是可以访问的,比如使用 XMLHttpRequest 来访问网络,可以使用navigator对象和location对象等,所以别灰心,大多数 API 也是可以用的。
思考
虽然学习了 Web Workers,也知道如何使用,但是目前来讲好像使用 Web Workers 解决问题的项目不多,通过搜索引擎发现很多库/工具都实现了 Web Workers呢,我个人还是很看好 Web Workers 滴:
🌟: useWorker 🌟: Threadjs 🌟: react-worker-image 🌟: worker-dom
欢迎大家一起交流哦🍺🍺🍺
References: