今天在开发中,遇到了这样一种场景。
有两个功能按钮:“申请排队”、“退出队列”,点击“申请排队”,将触发被一个名为pullingCurrentStatus函数包裹的定时器,基于axios定时的向web接口发起请求,以实现轮询的需求。 为了解决定时器是被包裹在另一个函数中的局部变量,无法直接在另外的一个方法中去引用定时器变量对象的,也就直接引用不了,我就没办法去关闭它的问题。我通过对定义一个中间全局变量的判断,实现“退出队列”按钮,触发另外的一个方法,在其中销毁定时器。详细的有兴趣可以看这里【link】本文的重点不在这里,不多做讨论。
首先,上面说的那种在函数体内部定义局部的定时器对象本身就是不是一种值得推荐的做法,事实证明我也因此遇到了棘手的问题,我遇到了这样的问题:
出现这个问题的原因,是因为定时器对象在实例化之前,没有被正确的销毁掉,导致被创建了多个实例,但是修改的是同一个全局的接受变量。也就是同时有多个定时器在执行,在修改同一个变量导致的。
为了解决这样的一个问题,以及示例在vue中,定时器如何被正确使用,这里写了一个demo。
简单的说,就是把定时器对象定义在data(){}
返回的对象中return{}
。然后每次调用前,都销毁一下实例。也就是说,我们定义了一个唯一的全局的定时器对象接收变量,这样就避免了出现多个定时器对象实例的情况。这不仅解决了实例多次被创建的问题,还方便于销毁实例。
<template>
<div>
<h1>DEMO</h1>
<P>这是一个定时器</P>
<p>现在是北京时间</p>
<p>{{ msg }}</p>
<button @click="startTheTimer">打开定时器</button>
<button @click="turnOffTimer">关闭定时器</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "",
Timer:null,
};
},
methods: {
startTheTimer() {
//调用前,先销毁定时器实例,初始化实例对象
if(this.Timer != null){
clearInterval(this.Timer);
}
this.Timer = setInterval(() => {
this.msg = new Date();
}, 1000);
},
turnOffTimer() {
clearInterval(this.Timer)
}
}
};
</script>