js使用webWorker实现多线程

js使用webWorker实现多线程

worker介绍:

  • worker线程在浏览器后台运行,不干扰主线程。
  • worker线程适用于计算高耗时的计算算法,以及轮询查询服务器状态的需求。
  • worker线程的环境与主线程不同,不能获取DOM元素,无法使用documentwindow以及parent等对象,但可以使用navigatorlocation对象。
  • worker线程中可以使用AJAX。
  • 主线程与worker线程的通信是拷贝关系,传值非传址,所以worker线程对数据的任何改变都不会影响到主线程。
  • 主线程与worker线程也可以传递二进制数据。

worker使用方法:

  1. 创建worker线程:

const worker = new Worker(’./js/worker/caculateVisibility.worker.js’);

  1. 向worker线程传入数据:

worker.postMessage(params)

  1. 监听worker线程的返回结果:

worker.onmessage = (evt) => {
console.log(evt.data);
}

  1. 主线程中关闭worker线程:

worker.terminate();

  1. worker线程中接收主线程发来的数据:

// self为worker线程的全局对象,类似于主线程的window对象
self.addEventListener(‘message’, (e) => {
console.log(e.data);
}

  1. worker线程中向主线程发送计算结果:

self.postMessage(result);

  1. worker线程关闭worker线程:

self.close();

  1. worker线程中加载外部文件:

// 需要注意的是,加载的外部文件的执行作用域依然是worker线程的作用域
// 可加载多个外部文件,用逗号分开即可
self.importScripts(’./caculate_visibility.js’);

  1. 主线程监听worker线程的错误:

worker.onerror(function (event) {
console.log([
'ERROR: Line ', e.lineno, ’ in ', e.filename, ‘: ‘, e.message
].join(’’));
});

原生js使用worker

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">
    <title>Web Workers basic example</title>
  </head>

  <body>
    <h1>Web<br>Workers<br>basic<br>example</h1>
    <div class="controls" tabindex="0">
      <form>
        <div>
          <label for="number1">Multiply number 1: </label>
          <input type="text" id="number1" value="0">
        </div>
        <div>
          <label for="number2">Multiply number 2: </label>
          <input type="text" id="number2" value="0">
        </div>
      </form>
      <p class="result">Result: 0</p>
    </div>
    <script src="main.js"></script>
  </body>
</html>

main.js

const first = document.querySelector('#number1');
const second = document.querySelector('#number2');

const result = document.querySelector('.result');

if (window.Worker) {
  const myWorker = new Worker("./worker.js");

  first.onchange = function() {
    myWorker.postMessage([first.value, second.value]);
    console.log('Message posted to worker');
  }

  second.onchange = function() {
    myWorker.postMessage([first.value, second.value]);
    console.log('Message posted to worker');
  }

  myWorker.onmessage = function(e) {
    result.textContent = e.data;
    console.log('Message received from worker');
  }
} else {
  console.log('Your browser doesn\'t support web workers.');
}

worker.js

onmessage = function(e) {
  importScripts('test.js')
  console.log(test);
  console.log('Worker: Message received from main script');
  const result = e.data[0] * e.data[1];
  if (isNaN(result)) {
    postMessage('Please write two numbers');
  } else {
    const workerResult = 'Result: ' + result;
    console.log('Worker: Posting message back to main script');
    postMessage(workerResult);
  }
}

test.js

function test() {
    console.log(test);
}

Vue中使用Worker

方法一

使用vue-worker包

npm i vue-worker

//main.js
import VueWorker from 'vue-worker'
Vue.use(VueWorker);

// 组件中使用
this.$worker.run(_workerFn, [monitor, time, data])
.then(res => {
    console.log('res', res);
})

function _workerFn(monitor, time, data) {
    // importScripts('monitor.js');
    // dosomething...
    return 'success';
}
方法二

使用原生worker,需要配置vue

vue.config.js

module.exports = {
  configureWebpack: config => {
    config.module.rules.push({
      test: /\.worker\.js$/,
      use: {
        loader: 'worker-loader',
        options: { inline: true, name: 'workerName.[hash].js' }
      }
    })
  },
}

caculate_visibility.js

const worker = new Worker('./js/worker/caculateVisibility.worker.js');//创建worker对象
const params = {
    tle: {
        line1: this.tle.line1,
        line2: this.tle.line2
    },
    location: {
        0: areaEntity.location[0],
        1: areaEntity.location[1]
    },
    startTime: new Date(this.viewer.clock.startTime),
    stopTime: new Date(this.viewer.clock.stopTime),
    step: 40,
    angle: rectSensorConfig.VerticalHalfAngle * 180 / Math.PI
};
worker.postMessage(params);// 向worker线程中传参
worker.onmessage = (evt) => { // 监听worker线程的反馈(计算好的结果会在这返回出来)
    const coverage = evt.data.length / 1440;
    const result = {
        satellite: this,
        timePoint: evt.data,
        coverage: coverage
    };
    satelliteWithAreaVisibilityMap[this.entity.name].set(areaEntity.entity.name, result);
}

caculateVisibility.worker.js

self.addEventListener('message', (e) => { // worker线程中监听主线程的传参
    self.importScripts('./caculate_visibility.js'); // worker线程中引入外部文件

    const result = caculateVisibulity(e.data.tle, e.data.location, e.data.startTime, e.data.stopTime, e.data.step, e.data.angle); // 此方法是引入文件中定义的

    self.postMessage(result); // 将计算结果返回给主线程

    self.close(); // 关闭worker线程(因为worker很耗资源,用完需要及时关闭)
})
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值