You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// main.jsvarmyWorker=newWorker('./worker.js');// worker.js,里面是worker线程运行的任务(执行的计算比较重的代码)onmessage=function(e){console.log('Message received from main script');varworkerResult='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 代码,那么控制台会报出一个错误
// main.jsif(!!window.SharedWorker){varmyWorker=newSharedWorker("worker.js");first.onchange=function(){myWorker.port.postMessage([first.value,second.value]);console.log('Message posted to worker');}second.onchange=function(){myWorker.port.postMessage([first.value,second.value]);console.log('Message posted to worker');}myWorker.port.onmessage=function(e){result1.textContent=e.data;console.log('Message received from worker');console.log(e.lastEventId);}}// worker.jsonconnect=function(e){varport=e.ports[0];port.onmessage=function(e){varworkerResult='Result: '+(e.data[0]*e.data[1]);port.postMessage(workerResult);}}
说实话,我本人接触的第一个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:
The text was updated successfully, but these errors were encountered: