web worker
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
注意
-
同源限制
分配给worker线程运行的脚本文件,必须与主线程的脚本文件同源。
-
DOM限制
worker线程无法读取主线程所在网页的DOM对象,也无法使用window、document对象。可以使用navigator、location对象。
-
通信联系
worker线程与主线程不在同一个上下文环境,他们之间不能直接通信,必须通过消息进行通信。
-
注意异步
worker通信是使用事件监听、异步回调处理的,所以实际使用中需要注意异步的问题。
-
脚本限制
worker线程不能执行alert()、confirm()方法,但是可以使用XMLHttpRequest发送ajax请求。
-
文件限制
worker无法读取本地文件,他所加载的脚本必须来自网络。
基本用法
主线程
- 主线程通过
new Worker()
新建一个worker线程。 - 通过
worker.postMessage(data)
向worker线程发送数据。data可以是各种类型的数据,也可以是二进制的数据。 - 通过
worker.onmessage = callback
接受worker发回的数据。
var worker = new Worker('worker.js');
worker.postMessage('hello');
worker.onmessage = function (e) {
console.log(e.data);
worker.terminate();
}
worker线程
- worker线程通过
this.onmessage = callback
接受主线程传来的数据。this指代子线程本身,也可以使用self.onmessage
,也可以省略onmessage
。 - worker线程通过
this.postMessage(data)
向主线程发送数据。
this.onmessage = function (e) {
console.log(e.data);
this.postMessage('You said: ${e.data}');
}
worker加载脚本
在worker内部使用importScripts()
加载其他脚本。
importScripts()
可以跨域加载js脚本- 通过
importScripts()
加载的脚本,就像在html里面使用script标签引入的脚本一样,脚本中定义的变量在worker中是全局的。所以需要注意多个脚本中不能有同名的变量。
importScripts('script1.js');
// 可以跨域加载脚本
importScripts('script1.js', 'http://192.168.11.162/script2.js', 'http://192.168.11.162:7070/static/js/script3.js');
错误处理
主线程使用worker.onerror = callback
监听worker线程内部发生的错误。
// 主线程
worker.onerror = function (e) {
console.log(e);
}
worker线程内部也可以监听error事件。
// worker线程
onerror = function (err) {
console.log(err);
}
关闭worker
为了节省系统资源,使用完毕建议关闭worker。
主线程使用worker.terminate();
关闭worker。
worker线程使用this.close();
关闭worker。