大家都知道,JavaScript是单线程的,也就是说,所有的任务只能在一个线程上完成,一次只能做一件事。前面的任务如果没有完成,后面就只能等着。所以,HTML5就提出了web Worker标准,表示JavaScript允许有多个线程,但是子线程完全受主线程的控制,并且子线程不能操作DOM,只有主线程可以操作DOM。所以 Web Worker 的最佳使用场景是执行一些开销较大的数据处理或计算任务。
什么是Web Worker ?
Web Worker 是HTML5标准的一部分,这一规范定义了一套API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中。
值得注意的是, Web Worker 规范中定义了两类工作线程,分别是专用线程Dedicated Worker和共享线程 Shared Worker。其中,Dedicated Worker只能为一个页面所使用,而Shared Worker则可以被多个页面所共享。
如何使用Worker?
使用的时候需要注意的几个地方
同源限制
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
DOM限制
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。
通信
Worker 线程和主线程不在同一个上下文环境,所以它们不能直接通信,必须通过发布订阅消息完成。
脚本限制
Worker 线程内不能执行alert()方法和confirm()方法,但是可以使用 XMLHttpRequest 对象发送 AJAX 请求。
文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。
如何创建一个Worker?
Worker构造函数,第一个参数是脚本的网址(必须遵守同源政策),该参数是必需的,且只能加载 JS 脚本,否则报错。
第二个参数是配置对象,该对象可选。它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程。
例如创建一个Worker:
const worker = new Worker('worker.js');
主线程与子线程如何通信?
基本原理就是在当前的主线程中加载一个只读文件来创建一个新的线程,两个线程同时存在,且互不阻塞,并且在子线程与主线程之间提供了数据交换的接口postMessage和onmessage。
例如,向Worker子线程发送消息:
// 第一种传递方式
worker.postMessage('我是主线程');
// 第二种传递方式
worker.postMessage({
// ArrayBuffer object
input: buffer
}, [buffer]);
worker.postMessage()方法的参数,就是主线程传给子线程 Worker 的数据。它可以是各种数据类型,包括二进制数据。
接收子线程Work发回的消息
worker.onmessage = function (event) {
console.log('子线程的消息:' + event.data)
}
worker.js子线程向主线程发送消息
self.postMessage('我是子线程')
接收主线程发来的消息
self.onmessage = function (event) {
console.log('主线程的消息:' + event.data)
}
self代表子线程自身,即子线程的全局对象。
以下是主线程与子线程的常用API
主线程中的,worker表示是 Worker 的实例:
worker.postMessage
主线程往worker线程发消息,消息可以是任意类型数据,包括二进制的数据
worker.terminate
主线程关闭worker线程
worker.onmessage
指定worker线程发消息时的回调
也可以通过 worker.addEventListener('message', cb) 的方式
worker.onerror
指定worker线程发生错误时的回调
同样也可以 worker.addEventListener('error', cb)
Worker线程中全局对象为 self,代表子线程自身,这时this指向self:
self.postMessage
worker线程往主线程发消息,消息可以是任意类型数据,包括二进制数据
self.close
worker线程关闭自己
self.onmessage
指定主线程发worker线程消息时的回调
也可以self.addEventListener('message', cb)
self.onerror
指定worker线程发生错误时的回调
也可以 self.addEventListener('error', cb)
self.name
Worker 的名字。该属性只读,由构造函数指定。
载入工具函数
importScripts('work1.js', 'work2.js', ...)
importScripts是同步方法,一旦importScripts方法返回就可以开始使用载入的脚本,而不需要回调函数。
共享线程 SharedWorker
共享线程是为了避免线程的重复创建和销毁过程,降低了系统性能的消耗,共享线程SharedWorker可以同时有多个页面的线程链接。
使用SharedWorker创建共享线程,也需要提供一个javascript脚本文件的URL地址或Blob,该脚本文件中包含了我们在线程中需要执行的代码,如下:
const sharedworker = new SharedWorker("sharedworker.js");
共享线程也使用了message事件监听线程消息,但使用SharedWorker对象的port属性与线程通信如下。
sharedworker.port.onmessage = function (event) {
console.log(event.data)
}
也可以使用SharedWorker对象的port属性向共享线程发送消息
sharedworker.port.postMessage('Hello World');

猜你喜欢
联络方式:
深圳 · 龙岗 · 大运软件小镇22栋302-308
电话:400 1828 580
邮箱:szhulian@qq.com



-
是什么限制你成为优秀设计师?
也许有一部分小伙伴会看不懂作者想表达什么,其实他就想告诉大家:不要过分纠结你使用的工具是什么,因为这对你的工作不会有太大帮助
-
如何打造一个拥有高转化率的企业官网?
通过网站访客行为数据的分析后,才能评价一个网站的好坏与否,不应该仅凭借个人主观去轻易定论,具有竞争力的网站并不是一蹴而就的
-
企业网站建设过程中关键因素
随着近年来互联网的高速发展以及网络基础设施的完善,越来越多的企业和个人投身到网络营销之中。其中还有非常多的中小企业,他们资源有限 ...
-
网页设计中的极简主义意味着全部吗?
最近我们编辑正在读一本由Brian Christian和Tom Griffiths合著的书——《指导生活的算法》。书的内容旨在展示计算机算法是如何在日常生活中发挥重要作用的,例如:在决定租哪间公寓之前需要考虑多少备选项...
-
对网站优化能够产生助力你知道吗?
现在很多网站花了钱做搜索引擎等竞价排名,然而却没有任何转化量,网站有流量但无人咨询,费用这么高的流量倘若在没有任何转化那就更冤枉了。建设网站既要美观大气也要利于优化排名...