Web Worker使用教程

Web Worker的作用

首先,我们都知道JS采用的是单线程模型,所有任务只能在一个线程上完成。

那Web Worker就是为JS创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。

Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。


Web Worker的注意点

  • 同源限制:分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
  • DOM限制:Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。
  • 通信联系:Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成

Web Worker的使用

主线程:

// 主线程
let worker = new Worker('work.js', {name: 'myWorker'}});

// 主线程调用以下方法,向 Worker 发消息
worker.postMessage('Hello World');
worker.postMessage({method: 'echo', args: ['Work']});

// Worker 完成任务以后,主线程就可以把它关掉。
worker.terminate(); // 不浪费资源

// 处理worker的error事件
worker.onerror(function (event) {
  // do something
});

worker.postMessage()方法的参数,就是主线程传给 Worker 的数据。它可以是各种数据类型,包括二进制数据。

// 主线程通过worker.onmessage指定监听函数,接收子线程(worker)发回来的消息
worker.onmessage = function (event) {
  console.log('Received message ' + event.data);
  doSomething();
}

function doSomething() {
  // 执行任务
  worker.postMessage('Work done!');
}
// 事件对象的 data 属性可以获取 Worker 发来的数据

Worker 线程:

// Worker 线程内部需要有一个监听函数,监听message事件
self.addEventListener('message', function (e) {
  // self.postMessage()方法用来向主线程发送消息。
  self.postMessage('You said: ' + e.data);
}, false);
// Worker 内部关闭自身
self.close()

若是在react使用Worker:

const workercode = () => {
    self.onmessage = function(event) {
      console.log('workercode ' + event.data);
      self.postMessage('done'); // here it's working without self
    }
};
// 把脚本代码转为string
let code = workercode.toString();
code = code.substring(code.indexOf("{")+1, code.lastIndexOf("}"));
   
const blob = new Blob([code], { type: "application/javascript" });
export const worker_script = URL.createObjectURL(blob);

react例子

// 主线程
import { worker_script } from './worker'

updateInfo(payload = {}) {
    this._updateInfo(payload)
    let worker = new Worker(worker_script, { name: 'myWorker' })
    const { pressions } = payload
    worker.onmessage = (event) => {
      const { routeMap = {}, codeMap = {} } = event.data
      console.log(routeMap, "routeMap", event.data)
      
      this.updateRouteMap(routeMap)
      this.updateCodeMap(codeMap)
      worker.terminate();
    }
    if (pressions && pressions.length > 0) {
      worker.postMessage(pressions);
    }
}



// worker 子线程: worker.js

const workercode = () => {
  onmessage = function(event) {
    const pressions = event.data
    console.log('workercode ' + event.data);
    let routeMap = {}
    let codeMap = {}
    if (pressions && pressions.length > 0) {
      pressions.forEach((item) => {
        if (item.route) {
          if (Array.isArray(item.route)) {
            item.route.forEach((path) => (routeMap[path] = true))
          } else {
            routeMap[item.route] = true
          }
        }

        if (item.code) codeMap[item.code] = true
      })
    }
   postMessage({routeMap, codeMap});
  }
};

// 把脚本代码转为string
let code = workercode.toString();
code = code.substring(code.indexOf("{")+1, code.lastIndexOf("}"));
   
const blob = new Blob([code], { type: "application/javascript" });
export const worker_script = URL.createObjectURL(blob);

使用场景:
加密数据;预取数据;预渲染;
复杂数据处理场景:某些检索、排序、过滤、分析会非常耗费时间,这时可以使用Web Worker来进行,不占用主线程。
预加载图片;

浏览器兼容性:

截图 (1).png

参考链接:Web Worker 使用教程

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值