Web Worker 初探
Posted 狮子还是喵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web Worker 初探相关的知识,希望对你有一定的参考价值。
什么是Web Worker?
Web Worker 是html5 提出的能够在后台运行javascript的对象,独立于其他脚本,不会影响页面的性能,也不会影响你继续对于页面进行操作。通俗点讲,就是后台打杂的小工。
Why Web Worker?
Javascript 是单线程执行的,即某一时刻,一次只能做一件事情。Javascript的单线程是为了保证对dom操作的统一性,即同一时刻不会既有删除和添加同一个dom的操作,为了保证
dom树不会混乱,但是单线程执行是对于当下强大的多核CPU的一种浪费,无法充分发挥计算机的性能。为了解决上述问题,就产生了web worker,但是既要满足保证对dom树的统一
性,又要支持多线程,这就决定了web worker在程序运行时的地位(特性)。
打个比方,程序的主线程就像是只有一个厨师长的厨房,厨师长要亲自操刀整个做菜流程,配菜,加料等。web worker 就像是厨师长招来的学徒,可以帮忙切菜,帮忙看火候,帮忙调制佐料,但又不会影响整个做菜的主流程(没有权限)。
所以web worker可以用于负责处理数据,或者执行可以延后的任务。
如何编写Web Worker
可以用VSCode 创建一个空白的文件夹,添加index.html,index.js,worker.js等文件。在index.html中引入index.js,接着在index.js中编写如下代码
function main(){ let worker = new Worker(\'worker.js\'); worker.postMessage(\'start\'); setTimeout(()=>worker.postMessage(\'end\'), 5000); worker.onmessage = function(event){ console.log(event.data); worker.terminate(); console.log(worker); } }
创建一个worker线程,只要通过new 关键字创建一个worker对象就行,传递的参数是woker线程要执行的js脚本,即我们现在给我们的小工分配了工作任务。
主线程和worker如何通信(厨师长如何给学徒安排任务)
主线程和worker之间的通信只能通过postMessage 和 onMessage 来进行,主线程通过postMessage来向worker传递信息,worker线程也是通过postMessage来向主线程传递信息,主线程通过onMessage来接收worker传递过来的信息。
worker线程通过addEventListener(\'message\', callback) 来监听主线程通过postMessage传递的信息。
下面是一个worker线程的简单例子
let number = 0; let intervalId = 0; this.addEventListener(\'message\', (e)=>{ const data = e.data; console.log(e.data); switch(data){ case \'start\': this.startCountNumber(); break; case \'end\': this.endCountNumber(); break; default: break; } }) function startCountNumber() { this.intervalId = setInterval(()=>{number++;console.log(number)}, 1000); } function endCountNumber() { clearInterval(this.intervalId); self.postMessage(\'done\') }
这是一个用来计数的worker,但是开始结束都由主线程开始,有兴趣的可以改写一下,主线程通知开始任务,当worker完成后,worker通知主线程任务完成。(厨师长安排任务给学徒,学徒做完后通知厨师长)。
当编写完这两个js文件后,可以通过打开浏览器访问index.html来对这个worker 进行测试。(index.html 不再贴出)
这里有一个值得注意的点,如果测试的时候是直接打开本地html文件,那么不能用chrome,chrome出于安全问题,会没法加载worker.js(CORS)。换用其它的浏览器即可,或者搭建本地服务器去运行亦可。
Web Worker注意点
为什么用厨师长和学徒的例子,就是为了体现web worker的几个注意点。
1. 学徒无法直接干预厨师长的工作(worker 只能通过postMessage 来向mai\'n thread 传递信息)
2. worker 没法直接读取或者操作dom,也没法使用window,parent等对象,但可以读取navigator, location对象。
3. web worker加载的脚本必需和主线程脚本同源(厨师长和学徒需要是一个厨房里的)
4.厨师长可以招多个学徒(主线程可以创建多个worker线程)
web worker 又分dedicated worker 和shared worker,有兴趣的可以深入了解下。
以及web worker的错误处理onError, web worker 发送异步请求等。
以上是关于Web Worker 初探的主要内容,如果未能解决你的问题,请参考以下文章