欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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文件一样 原理详情

相关标签: javascript