如何在前端Vue项目中使用web worker

678 阅读2分钟

应用场景

需要遍历一个很大的数组, 并且根据数组中的数据组装新数组,再渲染到页面

业务背景

通过操作canvas的像素点来一层一层改变canvas的颜色,如果不通过web worker会导致浏览器特别卡顿,一直在跑循环无法响应用户操作

好了,废话不多说,我只介绍一下我在项目中的使用,及需要注意的点

第一步: 创建worker, 在你需要使用到worker的地方去创建子线程,new Worker('worker子线程处理逻辑的文件路径'), 此处要注意的是webpack需要配置相关的路径,否则你只能放在根路径下,也就是public目录下 (我用的是vue cli3), 具体线程通信见图中注释

企业微信截图_16470790428073.png

this.publicPath = process.env.BASE_URL
// 创建子线程 this.workerPos 直接用变量存也可以,我是在组件内使用所有挂载到了实例上
this.workerPos = new window.Worker(`${this.publicPath}picParseWorker.js`)

// 监听子线程处理之后返回的数据
this.workerPos.onmessage = (res) => {
  console.log('2 主线程接收到子线程的结果', res)
  // 拿到返回的数据去处理对应的逻辑
}

// 给子线程发消息
this.workerPos.postMessage({
  type: 'getPos',
  data: this.imgData.data,
})

publicPath 就是我们在vue.config.js中配置的基础路径

企业微信截图_16470793301830.png

第二步,创建需要在子线程处理逻辑的子线程文件,在项目的public目录下创建picParseWorker.js文件(命名随意),此处要注意的是postMessage只能接收一个参数,需要以对象方式传参;

企业微信截图_16470792803453.png

onmessage = function (e) {
  console.log('1 主线程接收到子线程的结果',e)
  //通过请求获取数据
  if (e.data.type === 'getPos') {
    onHandlePos(e.data)
  } else if(e.data.type === 'setColor'){
    // onHandleSetColor(e.data)
  }
}

// 解析位置坐标
function onHandlePos(e) {
  var pixelPosition = []
  for(let i=pixs.length-1; i>=0;i-= 4){
    //处理相关逻辑
  }

  // 将处理结果反馈给主线
  postMessage(pixelPosition)
}

好了这样就可以实现通信

企业微信截图_16470800861799.png

最后当你离开页面或者不需要子线程时需要终止掉子线程,以免资源浪费

  beforeDestroy () {
    this.workerPos.terminate()
  }

实现中参考:blog.csdn.net/chengchengg…

共勉!