vue-worker

-

一般使用worker都是单独执行一个js脚本文件;最近发现一个vue插件,vue-worker,支持了传入一个方法,就可以让这个方法在worker线程执行;使用worker更加方便;

vue-worker地址:https://www.npmjs.com/package/vue-worker

安装:

npm install vue-worker --save

vue2使用:

import Vue from 'vue'
import VueWorker from 'vue-worker'
Vue.use(VueWorker)

可以用this.$worker调用

vue3使用:

import vueWorker from 'simple-web-worker'

主要用到run和create方法:

run:

this.$worker.run(func, [args]?)

func是在worker中运行的函数;

[args]是函数需要的参数,用数组盛放;

例子:

this.$worker.run((a, b) => {
    return a+b;
}, [1,2])
.then(res => {
    console.log(res) // 3
})
.catch(err => {
    console.log(err)

})

this.$worker.create([actions]?)

如果打算重用worker,需要用create

它生成一个实例,

通过它的postMessage()或postAll()方法运行确定的操作。

例:

const actions = [
  { message: 'func1', func: () => `Worker 1: Working on func1` },
  { message: 'func2', func: arg => `Worker 2: ${arg}` },
  { message: 'func3', func: arg => `Worker 3: ${arg}` },
  { message: 'func4', func: (arg = 'Working on func4') => `Worker 4: ${arg}` }
]
 
let worker = this.$worker.create(actions)

 

 发现这个插件不能够传入promise,有时候就有些不够好用;根据源码,稍微改了个简单的可以传入promise的插件:

promiseWorker.js

const  argumentError = function (r) {
  var e = r.expected,
    n = void 0 === e ? "" : e,
    t = r.received,
    o = r.extraInfo,
    i = void 0 === o ? "" : o;
  try {
    return new TypeError("You should provide " + n + "\n" + i + "\nReceived: " + JSON.stringify(t))
  } catch (r) {
    if ("Converting circular structure to JSON" === r.message) return new TypeError("You should provide " + n + "\n" + i + "\nReceived a circular structure: " + t);
    throw r
  }
}
const getType = (param) => {
  return Object.prototype.toString.call(param).replace(/[\[|\]]/g, '').split(/\s/)[1];
}
const makeResponse = function (r) {
  return "\n  self.onmessage = async (event) => {\n    const args = event.data.message.args\n    if (args) {\n      const result = await (" + r + ").apply(null, args)\n      self.postMessage(result)\n      return close()\n    }\n    \n      const result = await (" + r + ").apply(null, args)\n      self.postMessage(result)\n    return close()\n  }\n"
};
const createDisposableWorker = function (r) {
  var e = window.URL || window.webkitURL,
    n = new Blob([r], {
      type: "application/javascript"
    }),
    t = e.createObjectURL(n),
    o = new Worker(t);
  return o.post = function (r) {
    return new Promise(function (n, i) {
      o.onmessage = function (r) {
        e.revokeObjectURL(t), n(r.data)
      };
      o.onerror = function (r) {
        console.error("Error: Line " + r.lineno + " in " + r.filename + ": " + r.message), i(r)
      };
      o.postMessage({
        message: r
      });
    })
  }, o
}
const run = function () {
  let r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : null,
    e = arguments[1],
    n = getType(r) === 'Function',
    t = getType(e) === 'Array';
  if (n && t) {
    return createDisposableWorker(makeResponse(r)).post({
      args: e
    })
  }
  return n || console.error(argumentError({
    expected: "a function",
    received: r
  })), t || console.error(argumentError({
    expected: "an array",
    received: e
  })), null
}
export default run

使用:

const fn = (a) => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(a)
    }, 1000)
  })
};
run(fn, [1]).then(res => {
  console.log(res, 'res'); // 1
})

 

 

-

posted @ 2022-02-12 19:35  古墩古墩  Views(3778)  Comments(0Edit  收藏  举报