vue2中使用web worker启动定时器
vue2中使用web worker启动定时器,避免浏览器最小化或切换标签页时定时器不能按设定周期执行【一般是周期小于60s时,大于60s一般可正常执行】
- 1、添加worker-loader
- 2、修改vue.config.js
- 3、创建timer.worker.js
- 4、创建TimerWorker.js
- 5、使用TimerWorker启动定时任务
1、添加worker-loader
npm install worker-loader --save
2、修改vue.config.js
新增以下配置
config.module
.rule('workers')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.options({
inline: 'fallback' // 尝试内联,失败则回退到默认行为
})
3、创建timer.worker.js
self.timers = {}
self.onmessage = function(event) {
const { action, id, interval } = event.data
switch (action) {
case 'startTimer':
startTimer(id, interval)
break
case 'stopTimer':
stopTimer(id)
break
case 'stopAllTimers':
stopAllTimers()
break
}
}
function startTimer(id, interval) {
if (!self.timers[id]) {
self.timers[id] = setInterval(() => {
self.postMessage({ id })
}, interval)
}
}
function stopTimer(id) {
if (self.timers[id]) {
clearInterval(self.timers[id])
delete self.timers[id]
}
}
function stopAllTimers() {
Object.keys(self.timers).forEach(id => {
clearInterval(self.timers[id])
})
self.timers = {}
}
4、创建TimerWorker.js
import Worker from './timer.worker.js'
export default class TimerWorker {
worker;
timers;
constructor() {
this.start()
}
startTimer(id, interval, fun) {
if (this.worker && !this.timers[id]) {
this.timers[id] = fun
this.worker.postMessage({ action: 'startTimer', id, interval })
}
return this
}
stopTimer(id) {
if (this.worker && this.timers[id]) {
this.worker.postMessage({ action: 'stopTimer', id })
delete this.timers[id]
}
return this
}
stopAllTimers() {
if (this.worker) {
this.worker.postMessage({ action: 'stopAllTimers' })
this.timers = {}
}
return this
}
start() {
if (!this.worker) {
const worker = new Worker()
worker.onmessage = (event) => {
this.timers[event.data.id]()
}
this.worker = worker
this.timers = {}
}
return this
}
terminate() {
if (this.worker) {
this.stopAllTimers()
this.worker.terminate()
this.worker = undefined
this.timers = undefined
}
return this
}
}
5、使用TimerWorker启动定时任务
import TimerWorker from './TimerWorker'
export default {
...
created() {
this._timerWorker = new TimeWorker()
this.startTimer()
},
beforeDestroy() {
this._timerWorker.terminate()
},
methods: {
startTimer() {
this._timeWorker.startTimer('test', 100, () => {
console.log(new Date().getTime())
})
}
}
...
}