vue-worker:在vue中方便使用web worker

广告位招租
扫码页面底部二维码联系

因为公司的项目里面有一种case可以用w转载请注明出处:www.tangshuang.net原创内容,盗版必究。orker来解决,所以决定尝试一下。本来【本文受版权保护】转载请注明出处:www.tangshuang.net打算自己按照worker原理自己写一套,转载请注明出处:www.tangshuang.net【本文受版权保护】结果一google发现了vue-work原创内容,盗版必究。【版权所有,侵权必究】er这个插件,简直戳中痛点,打算用它来实转载请注明出处:www.tangshuang.net【本文受版权保护】现自己的需求。

本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。

vue-worker把复杂的web wo【版权所有,侵权必究】【本文首发于唐霜的博客】rker封装起来,提供一套非常简明的ap【版权所有,侵权必究】转载请注明出处:www.tangshuang.neti接口,使用的时候可以说像不接触work【本文首发于唐霜的博客】【本文首发于唐霜的博客】er一样方便。那么具体怎么使用呢?

未经授权,禁止复制转载。【本文受版权保护】【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。

安装本文作者:唐霜,转载请注明出处。

【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】未经授权,禁止复制转载。
npm i -S vue-worker

注册转载请注明出处:www.tangshuang.net

【原创内容,转载请注明出处】【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】
import Vue from 'vue'import VueWorker from 'vue-worker'import App from 'App.vue'
Vue.use(VueWorker)
new Vue({
   el: '#app',
  render: h => h(App) })

注册之后,你可以像this.$store本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net一样使用this.$worker

【关注微信公众号:wwwtangshuangnet】【本文受版权保护】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。

使用【版权所有】唐霜 www.tangshuang.net

本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net
export default {
 name: 'worker-test', data() {
   return {
    worker: null,
   }
 },
 mounted() {
   // 通过this.$worker.run这个方法,跑起一个worker,
   // worker是在另外的线程里面跑的,所以可以在run的第一个参数函数里面执行一个非常大计算的操作
   // run方法像Promise一样提供.then和.catch,then的参数就是run第一个参数函数的返回值
   this.worker = this.$worker.run(n => n + 10, [2])
    .then(res => console.log(res))
    .catch(e => console.log(e)) }, destroyed() {
   // 通过赋值null的方式,释放掉worker引用,这样就可以关闭worker,这是作者在github上说的
   this.worker = null
 },
}

API介绍【原创内容,转载请注明出处】

【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。原创内容,盗版必究。

下面来详细介绍一下vue-worker的著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】几个api,也就是方法method。

原创内容,盗版必究。【本文受版权保护】未经授权,禁止复制转载。

.run(fun, […ar【原创内容,转载请注明出处】【原创不易,请尊重版权】gs])

【转载请注明来源】原创内容,盗版必究。【未经授权禁止转载】【作者:唐霜】【版权所有】唐霜 www.tangshuang.net

上面已经看到了这个方法,而且也有注释说明本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。。注意第二个参数是一个数组,数组的个数和原创内容,盗版必究。本文作者:唐霜,转载请注明出处。第一个参数fun的形参个数是一样的。
【本文首发于唐霜的博客】未经授权,禁止复制转载。 你可能会有一个疑问:直接在fun函数体转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net内使用当前变量不就好了么?js本身的全局原创内容,盗版必究。【原创不易,请尊重版权】变量特性在这里不能用?这是因为worke【本文受版权保护】【版权所有,侵权必究】r是在另外一个线程中运行,跟当前页面内的【原创内容,转载请注明出处】【版权所有,侵权必究】js脚本不是在同一个线程,不共享内存空间本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。,所以直接在fun函数体里面使用另外一个【本文受版权保护】原创内容,盗版必究。线程的变量是找不到的,所以要通过函数参数【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】的形式进行传递。而传递的实质,是使用了w【原创不易,请尊重版权】【本文首发于唐霜的博客】orker的postMessage方法,【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】把第二个参数当做postMessage的【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】内容,具体你可以阅读这里【作者:唐霜】的源码。【版权所有】唐霜 www.tangshuang.net

【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。

run是一次性的,跑完这次,worker【原创不易,请尊重版权】【原创不易,请尊重版权】线程就会被关掉。想要持久化worker,未经授权,禁止复制转载。【本文受版权保护】可以使用下面的create来创建。

【转载请注明来源】本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】

.create([…acti本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】ons])

未经授权,禁止复制转载。【原创内容,转载请注明出处】【本文首发于唐霜的博客】

这个方法让你创建一个worker对象(注【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。意不是worker实例,你无法通过该对象原创内容,盗版必究。【原创不易,请尊重版权】直接操作worker,这个实例仅仅是一个未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。js object,提供了几个属性接口)转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】

本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net

actions是一个数组,数组的每个元素本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net是一个含有两个属性的对象:

【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。
export default {
  name: 'worker-test',
  data() {
    return {
     worker: null,
    }
  },
  created() {
    this.worker = this.$worker.create([
      {
        message: 'pull-data',
        func(data) {
          data.forEach(...)
          return data
        },
      },
      {
        message: 'run-task',
        func(id) {
          //...
        },
      }
    ])
  },
  mounted() {
    let data = ...
    this.worker.postMessage('pull-data', [data])
      .then(res => console.log(res))
  },
  destroyed() {
    this.worker = null
  },
}

你可以看到,实际上.run方法是crea未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.nette方法和postMessage方法的合【原创不易,请尊重版权】未经授权,禁止复制转载。体,一次性把两个方法的事都做了。

【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】

.postMessage(message本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.netid, […args])

【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。【转载请注明来源】

这个在上面的代码里面已经演示了。它不是t【本文首发于唐霜的博客】【原创不易,请尊重版权】his.$worker的方法,而是通过t本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】his.$worker.create之后【转载请注明来源】【本文首发于唐霜的博客】得到的object的一个方法。使用这个方【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net法跟worker原生的方法很像,当然,这【原创内容,转载请注明出处】【本文首发于唐霜的博客】里的messageid就是上面actio转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】ns数组里面的某个对象的message字未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。段对应的那个。而args就是你要传递的数【原创内容,转载请注明出处】未经授权,禁止复制转载。据。

本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】【作者:唐霜】

你可能又会问了,这里的[..args]是【转载请注明来源】著作权归作者所有,禁止商业用途转载。一个参数,还是说里面的元素才是参数。其实著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】很简单,[…args]被用作未经授权,禁止复制转载。原创内容,盗版必究。了.apply的第二个参数:func.apply(null, [...args]),所以,…args对应的就是【作者:唐霜】转载请注明出处:www.tangshuang.netfunc的参数。

【作者:唐霜】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net

.postAll([…arg【作者:唐霜】未经授权,禁止复制转载。s])

【原创内容,转载请注明出处】【转载请注明来源】原创内容,盗版必究。未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net

这里的postAll和上面的postMe转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】ssage一样,是create之后的那个【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.netobject的一个方法,而不是this.【转载请注明来源】本文版权归作者所有,未经授权不得转载。$worker的,所以使用的时候,也只能未经授权,禁止复制转载。【本文受版权保护】用在create之后。

【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】

它的参数是一个数组,但是这个数组的元素有转载请注明出处:www.tangshuang.net【作者:唐霜】三种形式,一种是不传,一种是string【本文首发于唐霜的博客】【本文受版权保护】:messageid,另一种是{mess【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。age, […func_ar转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。gs]}。其实都很好理解。

转载请注明出处:www.tangshuang.net原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net

不传【本文首发于唐霜的博客】

本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net

代表所有的actions都执行一次pos未经授权,禁止复制转载。转载请注明出处:www.tangshuang.nettMessage。

本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。

[string:messageid]【本文首发于唐霜的博客】

【转载请注明来源】【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】

代表对应的messageid的那个act【原创内容,转载请注明出处】【转载请注明来源】ion被执行postMessage。

【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】

[{message, […f【本文受版权保护】转载请注明出处:www.tangshuang.netunc_args]}]

【本文受版权保护】原创内容,盗版必究。未经授权,禁止复制转载。

给指定的messageid传参数。本文作者:唐霜,转载请注明出处。

【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】
export default {
  name: 'worker-test',
  data() {
    return {
      worker: null,
    }
  },
  created() {
    this.worker = this.$worker.create([
      {
        message: 'pull-data',
        func(data) {
          data.forEach(...)
          return data
        },
      },
      {
        message: 'run-task',
        func() {
          //...
        },
      }
    ])
  },
  mounted() {
  
    // 1. 不传
    this.worker.postAll().then([res1, res2] => {})
  
    // 2. 字符串形式
    let data = ...
    this.worker.postAll(['run-task']).then([res] => {}) // 仅'run-task'被postMessage
  
    // 3. 对象形式(混合形式)
    this.worker.postAll([
      'run-task',
      {
        message: 'pull-data',
        args: [data],
      },
    ]).then([res1, res2] => {})
  },
  destroyed() {
    this.worker = null
  },
}

比较难把握的就是,这里所有的传入都要采用【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】数组的形式,理解上需要稍微思考下。

【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】【作者:唐霜】著作权归作者所有,禁止商业用途转载。【作者:唐霜】

.register(action || 原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。[…actions])

【版权所有,侵权必究】【未经授权禁止转载】【版权所有,侵权必究】【本文首发于唐霜的博客】原创内容,盗版必究。

同理,也是在<worker>【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。的object对象上的方法。当你使用cr【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】eate之后,发现你的worker任务不【作者:唐霜】原创内容,盗版必究。够用,要追加一个action或多个,那么著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】可以使用register来追加。acti【转载请注明来源】原创内容,盗版必究。on(s)和create是一模一样的。

未经授权,禁止复制转载。【原创不易,请尊重版权】未经授权,禁止复制转载。【原创内容,转载请注明出处】

.unregister(message 本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net|| […messages]著作权归作者所有,禁止商业用途转载。【转载请注明来源】)

著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】【本文首发于唐霜的博客】【未经授权禁止转载】

和register有点像,意思是当你某一本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】个任务不想要了,可以通过unregist【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】er来取消这个任务。参数和registe【版权所有,侵权必究】【原创不易,请尊重版权】r不一样,直接使用messageid作为【本文受版权保护】原创内容,盗版必究。参数即可。

【本文首发于唐霜的博客】原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net
export default {
  name: 'worker-test',
  data() {
    return {
      worker: null,
    }
  },
  created() {
    this.worker = this.$worker.create([
      {
        message: 'pull-data',
        func(data) {
          data.forEach(...)
          return data
        },
      },
      {
        message: 'run-task',
        func() {
          //...
        },
      }
    ])
  },
  mounted() {
    // 1. 不传
    this.worker.postAll().then([res1, res2] => {})
  
    // 2. 字符串形式
    let data = ...
    this.worker.postAll(['run-task']).then([res] => {}) // 仅'run-task'被postMessage
  
    // 3. 对象形式(混合形式)
    this.worker.postAll([
      'run-task',
      {
        message: 'pull-data',
        args: [data],
      },
    ]).then([res1, res2] => {
      // 注意,这里then里面执行的是在主js线程里面执行的,所以可以直接用this.worker
      this.worker.unregister('run-task')
      // 当你注销掉了,那么下回你在post到run-task这个任务消息时,就啥都不会发生了
    })
  },
  destroyed() {
    this.worker = null
  },
}

关闭worker【本文受版权保护】

【本文受版权保护】【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。

在最前面的代码里面已经提到了,插件的作者本文作者:唐霜,转载请注明出处。【本文受版权保护】指出,你是没办法拿到worker原始实例著作权归作者所有,禁止商业用途转载。【本文受版权保护】的,所以也就无法调用worker.ter著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】minate()或者在worker线程内【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】部执行self.close()来关闭wo本文版权归作者所有,未经授权不得转载。【转载请注明来源】rker。create方法创建的不是wo原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】rker实例,所以它内部有,但是没有暴露【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】出来。所以插件没有关闭worker的方法本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。,你直接把worker对象释放掉即可。我原创内容,盗版必究。未经授权,禁止复制转载。翻阅了源码,发现它只在调用run方法时才【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net使用close,执行完run之后worker会被close本文作者:唐霜,转载请注明出处。,但是如果你使用create创建的wor【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】ker,是不会被close的它会一直存在【未经授权禁止转载】转载请注明出处:www.tangshuang.net,直到你关闭浏览器。

【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】

原理【原创不易,请尊重版权】

【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。【转载请注明来源】【作者:唐霜】著作权归作者所有,禁止商业用途转载。

web worker是通过一个浏览器提供【版权所有,侵权必究】【未经授权禁止转载】的Worker对象来创建的,创建的时候要原创内容,盗版必究。原创内容,盗版必究。传入指定的javascript文件作为w本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。orker线程的执行脚本。worker线【转载请注明来源】原创内容,盗版必究。程内的脚本有一些限制,比如只能拿到win【本文受版权保护】原创内容,盗版必究。dow.navigator的信息,不能拿【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net到完整的window对象。重点是,这里我【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。们没有提供一个js文件传入worker线【未经授权禁止转载】转载请注明出处:www.tangshuang.net程,vue-worker是怎么做到的呢?【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。它利用了Blob来创建一个可执行的二进制【转载请注明来源】本文作者:唐霜,转载请注明出处。上下文,在通过这个上下文来调用我们传入的【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。function,就好像在内存中虚拟了一著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。个内容是我们传入的function的js【原创不易,请尊重版权】【原创不易,请尊重版权】文件一样。具体的源码可以看这里未经授权,禁止复制转载。【本文受版权保护】

【原创不易,请尊重版权】【转载请注明来源】著作权归作者所有,禁止商业用途转载。【作者:唐霜】

2017-07-21 16945 ,

为价值买单,打赏一杯咖啡

本文价值169.45RMB