webworker

我们知道javascript是单线程,当主线程遇到大量计算或者复杂的业务逻辑时,会对我们的页面造成不好的用户体验。
webworker 很好的解决了这个问题,我们可以在主线程开启一个worker线程执行任务而不干扰用户界面(主线程)

worker描述

感觉还是有点抽象,举个例子。
那撸多(鸣人)这个5s真男人跟佩恩打架,开启了仙人模式,然而他的查克拉不够用,只能维持五秒钟仙人模式,他自己又不能一边打架一边聚集查克拉。这可怎么办?出了穿甲装的佩恩,一刀一个那撸多
这个时候那撸多灵机一动,想起了那个延时保健的小药丸…
咳咳,当然不是,我们大男主利用影分身在看不见的地方凝聚查克拉,凝聚完毕接触分身能量回到主体,嗯来劲了。成功打败佩恩
这里的影分身就相当于worker的作用,一个在你看不见的地方(其实是在浏览器中)默默工作的奉献者。在合适的时候将结果回传给主线程,然后消失,像是没来过一样

worker api使用

主线程中

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 脚本。

在vue里的配置以及使用

安装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);
	  },


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.预加载图片(当然最好懒加载)

webworker兼容性

点击这里查看兼容性

参考文档

Worker使用教程
worker MDN

Logo

前往低代码交流专区

更多推荐