Web Worker的使用

217 阅读1分钟

前言

在工作中有时候需要用到大量数据的计算,那么由于JS是单线程的,在计算数据时就会阻塞页面的渲染导致有很长的白屏时间,看起来就好像卡死了一样。 这时我们就可以使用Web Worker开辟一个独立于主线程的子线程来进行这些数据计算

在HTML中使用

在主线程中使用new Worker来创建Web Worker

const worker=new Worker(aURL, options)

它有两个参数:

  • aURL(必须)是一个DOMString 表示worker 将执行的脚本的URL。它必须遵守同源策略。
  • options (可选)它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程

在主线程中使用postMessage来发送数据,onmessage接收数据

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <h1 id="btn">Click Me</h1>
</head>

<body>
  <script>
    const Woker = new Worker("./woker.js")
    Woker.postMessage(5000000000);
    Woker.onmessage = (e) => {
      console.log(111, e.data);
    };
  </script>
</body>

</html>

在子线程中收发消息:

self.onmessage = e => {};
or:
self.addEventListener('message', function (e) {
  console.log(e.data)
}, false);

self.postMessage("...");
self.addEventListener('message', function (e) {
  let num = e.data;
  console.log(num)
  for (let i = 0; i <= num; i++) {
    if (i == num) {
      //2.向主线程发送数据
      console.log('finished')
      self.postMessage('任务完成啦!')
    }
  }
}, false);

在Vue中使用

注意事项:

  1. 安装worker-loader
  2. 在vue.config.js中作配置:
    chainWebpack: config => {
      config.module.rule('worker').test(/\.worker\.js$/).use('worker-loader').loader('worker-loader').options({ inline: 'fallback' })
    },
    
  3. worker文件要使用xxx.worker.js命名
<script>
import Woker from "./web5.worker.js";
export default {
  mounted() {
    let ul = document.getElementById("container");
    const W = new Woker()
    W.postMessage(100000)
    W.onmessage = (e) => {
      console.log(e.data)
      ul.innerHTML = (fragment);
    }
  };
</script>
self.addEventListener('message', function (e) {
  let num = e.data;
  let fragment = ''
  for (let i = 0; i < num; i++) {
    let li = `<li>${i}</li>`;
    fragment += li
  }
  self.postMessage(fragment)
}, false);

效果对比

使用Web Worker前: gaf9a-8bntq.gif 使用Web Worker后: yly1z-29xto.gif

可以清晰的看到,使用了Web worker后就不会再阻塞页面的渲染了