vue项目中如何使用多线程worker

项目背景:写一个定时器计时,但是和另外一个计时器产生事件循环问题,导致计时不准,所以把计时器放到另外一个线程里,避免两个计时器及渲染冲突

1.安装worker-loader

npm install worker-loader

2. 配置webpack

在vue.config.js文件的defineConfig里加上配置参数

 //多线程worker-loader配置项chainWebpack: config => {config.module.rule('worker-loader').test(/\.worker\.js$/).use({loader: 'worker-loader',options: {inline: true}}).loader('worker-loader').end()// 解决:worker 热更新问题config.module.rule('js').exclude.add(/\.worker\.js$/);}

3.使用

先在src目录下新建workers文件夹,接着在里面新建worker.js,在js文件里添加下面的测试代码:

addEventListener('message', e => {const { data } = econsole.log(data)setTimeout(() => {return postMessage('线程完成')}, 1000)
})
export default {}

之后就可以新建一个vue文件,加入下面代码进行测试:
引入js文件时需要使用worker-loader!@,并且路径是从src目录下开始数层级的,并非你执行的vue文件开始,这就是我一直不能正常跑起来的原因。

<script>
import Worker1 from 'worker-loader!@/workers/worker1'
export default {data(){return {events :[]}},mounted(){const worker1 = new Worker1()setInterval(()=>{worker1.postMessage('开启线程1')worker1.onmessage = e => {if(e.data.result == 1){that.events = e.data.data}}},10000)},
}

项目完整代码:
src => workers => worker.js

/**该多线程脚本用途
*在规定时间内快速走完24小时的时间
*//*** * @param {*} ste 定时器时间(计算的频率)* @param {*} countNum 计数的步伐* @param {*} totalTime 计时总时间,目前计时24小时的*/
const onTimer = (ste,countNum,totalTime) => {let count = 0  //计数器const total =  totalTime * 60 * 60let HH = "00"  //返回去的时针let MM = "00"  //返回去的分针let SS = "00"  //返回去的秒针let timer = setInterval(() => {if (count >= total) { // 到了24小时自动停止if (timer) {clearInterval(timer)timer = null}SS = "00"MM = "00"HH = "24"postMessage({code:0, HH ,MM ,SS })return}count += countNumlet countS = count % 60SS = formatter2(countS)let countM = Math.floor(count / 60) % 60MM = formatter2(countM)let countH = Math.floor(count / 60 / 60) % 60HH = formatter2(countH)postMessage({code:1, HH ,MM ,SS })return}, ste)
}
/*** * @param {*} time 传入时间改成两位数返回* @returns */
const formatter2=(time) => {let time2 = time+ ""let time3 = time2.split(".")[0]if (time3 < 10) {return '0' + time3} else {return time3}}addEventListener('message', e => {const { data } = eif (data.code === 1) {const {ste,countNum,totalTime} = dataonTimer(ste,countNum,totalTime)}
})
export default {}

主线程文件

<template><div class="container"><div class="digitalFlop timeBox">{{ H }}:{{ M }}:{{ S }}</div><div class="date">{{ year }} 年 {{ month }} 月 {{ day }} 日</div><div class="date opend">当前开机数</div><dv-digital-flop :config="configOpen" class="digitalFlop center"/><div class="date closed">当日开机总数</div><dv-digital-flop :config="configClose" class="digitalFlop bottom"/><div id="map"></div></div>
</template><script>
import { newgaode, getTerminal, getTime } from '@/api/table'
import { Scene, PointLayer, Popup } from '@antv/l7'
import { GaodeMap } from '@antv/l7-maps'
import Worker from 'worker-loader!@/workers/worker'let layer = null //底层点位图实例对象
let layer2 = null //中间层点位图实例对象
let layer3 = null //顶层点位图实例对象
let layer4 = null //顶层点位图实例对象let param = -1  //发送请求的计数器
const timeStep = 1.5 * 1000  //  每次递归请求的时间间隔,单位毫秒
const ste = 20  //左上角时间的递归频率
export default {name: 'DayofvisionVera',data() {return {array: [], //最底层图层的数组topArray: [], //最顶层图层的数组scene: null, //全局的场景最底层搞得地图的实例对象year: '-', //年month: '-', //月day: '-', //日configOpen: {//展示开机数量的翻牌器style: {fontSize: 55,fill: '#fff'},number: [0],content: '{nt}'},configClose: {//展示关机数量的翻牌器style: {fontSize: 55,fill: '#fff'},number: [0],content: '{nt}'},paramData : this.getParam(15),//切割后的参数timerOne: null,//递归函数里的定时器timeLater:null,//为了等背景地图全部加载完成再进行请求点位数据H:"00",//时M:"00",//分钟S:"00",//秒}},created() {if (this.timerOne) {clearInterval(this.timerOne)this.timerOne = null}// 获取数据的那一天this.getDataTime()},mounted() {//初始化地图this.$nextTick(() => {this.createMap()});},beforeDestroy: function () {//实例销毁前清除于定时器if (this.timerOne) {clearInterval(this.timerOne)this.timerOne = null}},methods: {// 初始化地图createMap() {this.scene = new Scene({id: 'map',map: new GaodeMap({center: [120.7, 29.2], //中心经度加大向右移动,纬度加大向上移动// center: [110, 37], // 展示全国的时候用这个// zoom: 3.8, // 展示全国的时候用这个// minZoom: 3,// 展示全国的时候用这个zoom: 7.1, //放大比例maxZoom: 15,minZoom: 4,style: 'dark', //风格})})// 创建this.scene.on('loaded', async () => {// 获取所有服务器数据newgaode().then(res => {if (res.code === 200) {this.array = res.datathis.array4 = [...res.data]// 最底层最暗layer = new PointLayer({}).source(this.array, { parser: { type: 'json', x: 'l', y: 't' } }).shape('simple') //点的形状.size('size', size => 4).color('#0F1C3E')//#0F1C3E从未开机(最暗色)  #0E316F开后关机(次暗色) #2273FF开机(最亮).style({ opacity: 0.8, strokeWidth: 0 })//中间层次暗层layer2 = new PointLayer({ zIndex: 10 }).source(this.array, { parser: { type: 'json', x: 'l', y: 't' } }).shape('simple').size('size', size => 4).color('s', s => (s === '0' ? '#0E316F' : '')).style({ opacity: 0.8, strokeWidth: 0 })// 顶层亮层layer3 = new PointLayer({ zIndex: 20 }).source(this.array, { parser: { type: 'json', x: 'l', y: 't' } }).shape('simple') .size('size', size => 4).color('s', s => (s === '1' ? '#2273FF' : '')).style({ opacity: 0.8, strokeWidth: 0 })// 最顶层透明层layer4 = new PointLayer({ zIndex: 30 }).source(this.array4, { parser: { type: 'json', x: 'l', y: 't' } }).shape('simple').size('size', size => size ? 13 : 4 ).color('color', color => (color ? '#2273FF' : 'rgba(0,0,0,0)')).style({ opacity: 0.8, strokeWidth: 0 })this.scene.addLayer(layer)this.scene.addLayer(layer2)this.scene.addLayer(layer3)this.scene.addLayer(layer4)this.timeLater = setTimeout(()=>{// 多线程计时器,主线程只留一个定时器this.onManyThread()// 开启递归请求数据this.getTerminalData()// 绑定鼠标移入事件this.mouseEnter()clearInterval(this.timeLater)this.timeLater = null},2000)}})})},// 递归请求所有时间点的数据getTerminalData(){this.timerOne = setTimeout(()=>{param += 1if (this.paramData[param]) {this.getTerminalData()this.handlerList(this.paramData[param])//用来请求接口}else{clearInterval(this.timerOne)this.timerOne = null}},timeStep)},// 请求所有点位数据handlerList(time){getTerminal({time}).then(res => {if (res.code == 200) {const data = res.dataif(!data[0]) retunconst resKey = Object.keys(data[0])[0]const cur = data[1][resKey]const tod = data[2][resKey]const bigArray=data[0][resKey]layer2.setData(bigArray)layer3.setData(bigArray)// 更新左上角开机数量this.powerOnNum(cur,tod)}})},/*** 开机数量更新* @param {*} current 当前开机数量* @param {*} today 当日开机数量*/powerOnNum(current,today){//更新当前开机点位的数量let opened = currentthis.configOpen.number = [Number(opened)]  this.configOpen = { ...this.configOpen }//更新当前关机点位的数量let cumulative = todaythis.configClose.number = [Number(cumulative)]this.configClose = { ...this.configClose }},/*** 计算参数的方法* @param {*} spacing 间隔多少分钟,单位分钟*/getParam(spacing){if(!spacing) []let timeParam = []let count = -spacinglet count2 = 0let interval = spacinglet length = Math.ceil(24*60 / interval)for (let index = 0; index < length; index++) { count += intervallet MM = count % 60if (MM<10) {MM = "0" + count % 60}else{MM = count % 60}let HH  = Math.floor(count / 60) % 60if (HH<10) {HH = "0"+Math.floor(count / 60) % 60}else{HH = Math.floor(count / 60) % 60 == 24 ? "00" : Math.floor(count / 60) % 60}let startTime = `${HH}:${MM}`count2 += intervallet MM2 = count2 % 60if (MM2<10) {MM2 = "0"+count2 % 60}else{MM2 = count2 % 60}let HH2  = Math.floor(count2 / 60) % 60if (HH2<10) {HH2 = "0"+Math.floor(count2 / 60) % 60}else{ HH2 = Math.floor(count2 / 60) % 60 == 24 ? "00" : Math.floor(count2 / 60) % 60}let endTime = `${HH2}:${MM2}`timeParam.push(`${startTime}-${endTime}`)}return timeParam},// 获取数据的那一天时间getDataTime(){getTime().then(res=>{if(res.code == 200){let date = res.data.split("-")this.year = date[0]this.month = date[1]this.day = date[2]}})},// 新的绑定鼠标事件mouseEnter(){layer4.on('mousemove', e => {const popup = new Popup({offsets: [0, 0], //偏移量closeButton: false, //是否展示右上角关闭xmaxWidth: '500px', //弹窗最大宽度closeOnClick: true //点击地图关闭弹窗}).setLnglat(e.lngLat).setHTML(`<span style="user-select:text;cursor:default;">终端名称: ${e.feature.d}</span><br><span style="user-select:text;cursor:default;">经纬度: ${e.feature.l}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${e.feature.t}</span>`)this.scene.addPopup(popup)//鼠标划过变大点位this.array4.forEach(item => {item.color = item.v === e.feature.v item.size = item.v === e.feature.v})layer4.setData(this.array)})},// 多线程计时器onManyThread(){const worker = new Worker()const totalTime = 24//展示24小时的计时const duration = timeStep * this.paramData.lengthconst countNum = Number((totalTime * 60 * 60 * ste / duration).toFixed(2))//countNum步伐worker.postMessage({code:1,ste,countNum,totalTime})//code是否开始,ste频率worker.onmessage = e => {const { data } = eif (data.code === 1) {const {HH,MM,SS} = datathis.H = HHthis.M = MMthis.S = SS}else{worker.terminate()} }}}
}
</script><style lang="scss" scoped>
.container {margin: -10px -12px;.digitalFlop {width: 160px;height: 50px;position: absolute;left: 30px;// top: 30px;top: 90px;z-index: 99;}.timeBox{color: #fff;font-size:58px;top: 83px;left: 95px;width: 250px;height: 58px;line-height: 58px; }.date {// background-color:green;height: 24px;line-height: 24px;font-size: 22px;color: #fff;position: absolute;left: 110px;// top: 43px;top: 150px;z-index: 99;}.opend {left: 150px;top: 305px;}.closed {width: 150px;text-align: center;left: 135px;top: 458px;}.center {width: 150px;// top: 90px;// left: 365px;top: 245px;left: 130px;}.bottom {width: 150px;// top: 90px;// left: 535px;top: 398px;left: 130px;}#map {height: 98%;width: 100%;justify-content: center;::v-deep.l7-popup-tip {border-top-color: #225cff !important;}::v-deep.l7-popup-content {background-color: rgba(0, 0, 0, 0.7) !important;border: 1px solid #225cff;color: #226eff;font-size: 600;}::v-deep.l7-control-logo {display: none;}::v-deep.amap-copyright {display: none !important;height: 0 !important;font-size: 0px !important;}}
}
</style>

antvl7绘制地图以及vue项目中使用多线程worker相关推荐

  1. 百度地图在VUE项目中插入点位及点位信息弹框

    在项目中需要使用地图功能,效果图如下: 具体步骤如下: 1.申请百度地图密钥 2.安装vue-baidu-map 3.在main.js中引入vue-baidu-map.js import BaiduM ...

  2. 百度地图的使用方法,如何在Vue项目中使用百度地图

    关于百度地图的解释 百度地图又称LBS:LocationBussinessServer,是基于定义位置的商业服务,现在常用的地图有百度地图和高德地图居多 官网入口 https://lbsyun.bai ...

  3. vue项目中使用echarts和china.js实现中国地图

    在echarts最新的5.4.0版本中,已不能直接引用china.js来绘制中国地图,需要我们自己下载china.js包 在网上查找资料,大部分是在index.html文件中直接引入echarts和c ...

  4. 在vue项目中使用高德地图JS API

    在vue项目中使用高德地图JS API,而不是amap依赖包~ 一. 必做的准备工作 注册账号并申请key 首先,注册开发者账号,成为高德开放平台开发者 登陆之后,在进入「应用管理」 页面「创建新应用 ...

  5. 在vue项目中使用高德地图

    需求很重要,有需求你才有努力解决问题的方向,加油! 在我们使用vue构建项目的时候,难免在业务需求上会遇到使用高德地图的时候,这时候问题就来了. 我们该怎么在vue项目中插入高德地图?通过度娘我知道了 ...

  6. vue项目中使用百度地图api完成自定义搜索功能(包含搜索详细地理位置)

    需求描述: 在vue项目中,有时候,我们需要自定义百度地图的一些功能.譬如,现在的需求,就是需要自定义搜索内容和结果展示. 类似如下页面的功能: 首先在vue项目中,我们可以使用 vue-baidu- ...

  7. vue项目中 使用百度地图 轨迹动画

    在上篇博客中,介绍了如何在vue项目中集成百度地图,这篇博客主要是说如何在vue项目中使用轨迹动画 在项目开发过程中,比如你需要实时的观察一个人的行走路线,行走过程.  这个时候我们就需要在地图上使用 ...

  8. vue项目中使用百度地图

    安装 首先在vue项目中,我们可以使用 vue-baidu-map 插件来替代直接引入百度地图js sdk. 官方文档 JavaScript API v2.0类参考 npm install --sav ...

  9. Vue项目中使用Echarts地图(精确到区)

    使用地图需要获取地图的json文件 这里是免费获取地图json 在原本Echarts图变中你看到的代码是这样的: var uploadedDataURL = "https://geo.dat ...

最新文章

  1. 理解AMD ,CMD,CommonJS规范
  2. 第十八讲 傅里叶变换
  3. 文巾解题 876. 链表的中间结点
  4. C++ int转string
  5. 浅析Banner设计
  6. 从龙门镖局看自动化测试
  7. python中title用法_在CSV fi中使用Title()
  8. 2020云栖大会奖品大盘点(持续更新中)
  9. JAVA构造对象的几种方式(构建器、构造器)
  10. 正则只能小于0负数_2019–2020学年七年级数学期末考试考点之正数与负数考点详解...
  11. ehcache使用_Java 程序员如何使用 Shiro 框架
  12. (计算机组成原理)第一章计算机系统概述-第四节:计算机的性能指标
  13. Eclipse JSP 页面设置 charset=UTF-8
  14. sqlite3---终端操作
  15. CS224N刷题——Assignment2.3_RNN:Language Modeling
  16. java 三子棋_java三子棋,高手帮忙
  17. 苹果手机如何用计算机,电脑怎么控制iPhone手机
  18. 办公小技巧:excel列宽在哪里设置
  19. 如何成为一个具有批判性思维的人?
  20. 使用redis缓存技术实现省市区三级联动

热门文章

  1. JS基础_js一元运算符
  2. zipkin安装及启动
  3. Linux的sed命令详解大全
  4. 不会解析配置文件?1秒钟应用到项目中
  5. 群雄逐鹿 互联网家装市场烽烟四起
  6. [转]秀下我的瓦伦西亚
  7. python下载pymysql_Python pymysql
  8. 从键盘输入一个人的姓和名,然后将姓和名的首字母变成大写字母
  9. 《微店赚钱一册通 ——开店+营销+推广 实战全攻略》一一1.3 商家纷纷试水微信营销...
  10. windows10 AppStore安装 应用商店重新安装