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 })
-