Web Worker在vue中的使用
程序员文章站
2022-07-03 16:07:20
...
install
yarn add vue-worker
usage
// main.js
import VueWorker from 'vue-worker'
Vue.use(VueWorker)
// 注册之后就在Vue的原型对象上挂载了$worker,您可以使用this.$worker来访问使用worker
.vue文件中
// 通过this.$worker.run这个方法,跑起一个worker,
// worker是在另外的线程里面跑的,所以可以在run的第一个参数函数里面执行一个非常大计算的操作
// run方法像Promise一样提供.then和.catch,then的参数就是run第一个参数函数的返回值
mounted(){
this.worker = this.$worker.run(n => n + 10, [2])
.then(res => console.log(res)) //12
.catch(e => console.log(e)) },
},
destroyed() {
// 通过赋值null的方式,释放掉worker引用,这样就可以关闭worker,这是作者在github上说的
this.worker = null
},
API介绍
.run(fun, [...args])
/**
第一个参数是一个函数,第二个参数是一个数组,数组的个数和第一个参数fun的形参个数是一样的
run是一次性的,跑完这次,worker线程就会被关闭。想要持久化worker,可以使用下面的create来创建。
**/
.create([...actions])
/***
这个方法让你创建一个worker对象(注意不是worker实例,你无法通过该对象直接操作worker,这个实例仅仅是一个js object,提供了几个属性接口)。
actions是一个数组,数组的每个元素是一个含有两个属性的对象:
**/
export default {
name: 'worker-test',
data() {
return {
worker: null,
}
},
created() {
this.worker = this.$worker.create([
{
message: 'work-task-1',
func(data) {
// 处理data数据
return data
},
},
{
message: 'work-task-2',
func(data) {
// 处理data数据
return data
},
}
])
},
mounted() {
let data1 = '我想成为前端大牛'
let data2 = '坚持就是胜利'
this.worker.postMessage('work-task-1', [data1]).then(res => console.log(res))
this.worker.postMessage('work-task-2', [data2]).then(res => console.log(res))
},
destroyed() {
this.worker = null
},
}
/***
不传
代表所有的actions都执行一次postMessage。
[string:messageid]
代表对应的messageid的那个action被执行postMessage。
[{message, [...func_args]}]
给指定的messageid传参数。
**/
// 1. 不传
this.worker.postAll().then([res1, res2] => {})
// 2. 字符串形式
let data = ...
this.worker.postAll(['work-task-1']).then([res] => {}) // 仅'work-task-1'被postMessage
// 3. 对象形式(混合形式)
this.worker.postAll([
'work-task-1',
{
message: 'work-task-2',
args: [data],
},
]).then([res1, res2] => {
// 注意,这里then里面执行的是在主js线程里面执行的,所以可以直接用this.worker
this.worker.unregister('work-task-2')
// 当你注销掉了,那么下回你在post到run-task这个任务消息时,就啥都不会发生了
})
关闭worker
关闭worker
在最前面的代码里面已经提到了,插件的作者指出,你是没办法拿到worker原始实例的,所以也就无法调用worker.terminate()或者在worker线程内部执行self.close()来关闭worker。create方法创建的不是worker实例,所以它内部有,但是没有暴露出来。所以插件没有关闭worker的方法,你直接把worker对象释放掉即可。我翻阅了源码,发现它只在调用run方法时才使用close,执行完run之后worker会被close,但是如果你使用create创建的worker,是不会被close的它会一直存在,直到你关闭浏览器。
原理
web worker是通过一个浏览器提供的Worker对象来创建的,创建的时候要传入指定的javascript文件作为worker线程的执行脚本。worker线程内的脚本有一些限制,比如只能拿到window.navigator的信息,不能拿到完整的window对象。重点是,这里我们没有提供一个js文件传入worker线程,vue-worker是怎么做到的呢?它利用了Blob来创建一个可执行的二进制上下文,在通过这个上下文来调用我们传入的function,就好像在内存中虚拟了一个内容是我们传入的function的js文件一样 原理详情