什么是WEB-WORKER?
-
由于JAVASCRIPT语言采用的是单线程模型,所有任务只能再一个线程上执行。早期得计算机是单核心所以没有问题。但是随着计算机能力得增强,特别是多核CPU的出现。单线程就带来很大的不便,无法充分发挥计算机的计算能力。
-
所以在HTML5的规范中提供了一个多线程的解决方案,这就是WEB-WORKER
-
WEB-WORKER允许JAVASCRIPT创造多线程环境,允许主线程创建WORKER线程,将任务分配在后台运行。这样高延迟,密集型的任务可以由WORKER线程负担,主线程负责UI交互就会很流畅,不会会阻塞或拖慢
-
浏览器支持
- IE10及以上版本,Firefox,Chrome,Safari和Opera都支持WebWorker
- 一般会在使用前增加前置校验,检测当前浏览器版本是否支持
if (Worker) { //supported,coding } else { //not supported,warning }
怎样使用WEB-WORKER?
- 主线程使用new命令调用Worker()构造函数创建一个Worker线程
var worker = new Worker('xxxxx.js')- Worker构造函数接收参数为脚本文件路径
- 主线成指定监听函数监听Worker线程的返回消息
worker.onmessage = function (event) {console.log(event.data)}data为Worker发来的数据
- 由于主线程与Worker线程存在通信限制,不再同一个上下文中,所以只能通过消息完成
worker.postMessage("hello world")worker.postMessage({action: "ajax", url: "xxxxx", method: "post"})
- 当使用完成后,如果不需要再使用可以在主线程中关闭Worker
worker.terminate()- Worker也可以关闭自身,在Worker的脚本中执行
self.close()
这样在Worker中使用其他脚本
- 如果需要引用其他脚本可以使用
importScriptsimportScripts('scripts1.js')- 该方法可以同时加载多个脚本
importScripts('scripts1.js','scripts2.js')
错误的处理
- 主线成可以监听Worker是否错误,如果有错误则会触发主线成的error事件
worker.onerror(function (evet) {
// ...
})
数据通信
-
主线程与Worker之间通信时拷贝的方式进行,即是传值而不是传址。Worker中对通信数据的修改并不会影响到主线程。
事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原
-
但是拷贝的形式做数据传输会造成性能问题,比如主线程向Worker发送几百MB的数据,默认情况下,浏览器会生成一份拷贝。为了解决这个问题,JAVASCRIPT允许主线程将二进制数据直接转移给Worker,但是转移控制权后,主线程就不再能使用这些数据。这是为了防止多个线程同时修改数据的情况发生。
-
这种转移数据控制权的方法叫做 Transferable Objects 这使得主线程可以快速的把数据移交给子线程。不会产生性能负担
-

场景
- 心跳检测
- 前端会定期检测后端服务的可用情况,一般情况下处理都是通过开启定时轮询发送ajax检测。这就会占用主线程资源
- 所以可以放在Worker中进行处理.出现异常再通知主线程渲染UI给予提示等操作
优点与缺点
- 优点
- 独立于主线程,不造成阻塞
- 非常适合处理高频、高延时的任务
- 可以内部做队列机制,做为延时任务的缓冲层
- 缺点
- 无法操作DOM,无法获取window, document, parent等对象
- 遵守同源限制, Worker线程的脚本文件,必须于主线程同源。并且加载脚本文件是阻塞的
- 不当的操作或者疏忽容易引起性能问题
参考资料