我们知道javascript是单线程,当主线程遇到大量计算或者复杂的业务逻辑时,会对我们的页面造成不好的用户体验。
webworker 很好的解决了这个问题,我们可以在主线程开启一个worker线程执行任务而不干扰用户界面(主线程)
感觉还是有点抽象,举个例子。
那撸多(鸣人)这个5s真男人跟佩恩打架,开启了仙人模式,然而他的查克拉不够用,只能维持五秒钟仙人模式,他自己又不能一边打架一边聚集查克拉。这可怎么办?出了穿甲装的佩恩,一刀一个那撸多
这个时候那撸多灵机一动,想起了那个延时保健的小药丸…
咳咳,当然不是,我们大男主利用影分身在看不见的地方凝聚查克拉,凝聚完毕接触分身能量回到主体,嗯来劲了。成功打败佩恩
这里的影分身就相当于worker的作用,一个在你看不见的地方(其实是在浏览器中)默默工作的奉献者。在合适的时候将结果回传给主线程,然后消失,像是没来过一样
主线程中
Worker.onerror:指定 error 事件的监听函数。
Worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。
Worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
Worker.postMessage():向 Worker 线程发送消息。
Worker.terminate():立即终止 Worker 线程。
示例
//实例化一个线程
let myworker = new Worker('worker.js')
//向worker线程 发送信息
myworker.postMessage({name:'kk',finshed:false})
//接受worker线程
myworker.onmessage = (event)=>{console.log(event.data)}
//关闭worker线程 worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。
myWorker.terminate();
```
在worker.js中
```js
//监听接收 主线程的参数
onmessage = function(event){
// you can start ajax
let result = ...
//将计算结果回传给主线程
postMessage(result);
//workers 也可以调用自己的 close 方法进行关闭
close();
//self.close()
}
onerror = function (event) {
console.log(event.message);//可读性良好的错误消息
console.log(event.filename)//发生错误的文件名
console.log(event.lineno) //发生错误时所在脚本文件的行号
self.close()
}
注意: 在主线程中使用时,onmessage和postMessage() 必须挂在worker对象上,
而在worker中使用时不用这样做。原因是,在worker内部,worker是有效的全局作用域。
worker 线程中
self.name: Worker 的名字。该属性只读,由构造函数指定。
self.onmessage:指定message事件的监听函数。
self.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
self.close():关闭 Worker 线程。
self.postMessage():向产生这个 Worker 线程发送消息。
self.importScripts():加载 JS 脚本。
安装worker-loader
npm install worker-loader --save-dev
文件代码
### vue.config.js 文件
config.module
.rule("worker-loader")
.test(/\.worker\.(c|m)?js$/i)
.use("worker-loader")
.loader("worker-loader")
.options({
filename: "[name].[contenthash].worker.js",
})
.end();
### my.worker.js 文件
//引入js 文件
// 脚本的下载顺序不固定,但执行时会按照传入 importScripts() 中的文件名顺序进行。
//这个过程是同步完成的;直到所有脚本都下载并运行完毕,importScripts() 才会返回
importScripts('foo.js', 'bar.js','ajax.js');
onmessage = function(event){
//工作线程接收到主线程的消息
let data = 10
//向主线程发送消息
console.log(event.data);
postMessage(data);
};
### file.vue 文件
import Worker from "@/utils/my.worker.js";
mounted() {
this.worker = new Worker();
// console.log(this.worker);
},
1.同源限制
Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
2. DOM限制
document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象
3.脚本限制
Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
4.文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络
1.轮询更新数据状态
2.复杂数据处理场景,加密数据
3.大文件上传(小作者我就是开发这个,接触了worker)
4.预加载图片(当然最好懒加载)