关于HTML5的Web Worker你了解多少?

2020-07-31 08:13:00 2686 2 编辑:深圳网站设计 来源:互联网

大家都知道,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');

深圳网站设计.jpg

本站文章均为深正网站建设摘自权威资料,书籍,或网络原创文章,如有版权纠纷或者违规问题,请即刻联系我们删除,我们欢迎您分享,引用和转载,但谢绝直接搬砖和抄袭!感谢...
关注深正互联

15

技术从业经验

多一份方案,会有收获...

联系深正互联,免费获得专属《策划方案》及报价

在线咨询
微信交谈
拒绝骚扰,我们只想为给您带来一些惊喜...
多一份免费策划方案,总有益处。

请直接添加技术总监微信联系咨询

深正互联微信
扫描即可沟通