#vue如何在函数体外销毁被函数包裹的局部定时器 #vue如何销毁局部定时器
该方案已被废弃,请点击【这里】以查看更好的解决方案
pullingCurrentStatus(BackData) {
let PullingCurrentStatusTimer = setInterval(() => {
this.$axios
.post(this.HOST + "/api/pullingcheckstatus", {
//轮询当前申请的status值
PullingTimeNode: BackData,
})
.then((result) => {
if (result.data.CheckedStatus == "applying") {
this.status = "提交成功,等待审核...";
this.ReturnStatus = "applying";
this.bindcolor = "#ff840f";
console.log(result.data.CheckedStatus);
} else if (result.data.CheckedStatus == "able") {
this.status = "您已经处于队列中";
this.ReturnStatus = "able";
this.bindcolor = "#07c160";
this.getTheQueuingData()//轮询前方车辆以及排队人数
console.log(result.data.CheckedStatus);
this.ifShowNoticeBar = true;
} else if (result.data.CheckedStatus == "denied") {
this.status = "管理员驳回了您的申请";
this.ReturnStatus = "denied";
this.bindcolor = "#fd0303";
console.log(result.data.CheckedStatus);
clearInterval(PullingCurrentStatusTimer); //停止定时器
}
})
.catch((err) => {
console.log(err);
});
}, 2000);
},
简单的说明,这部分的逻辑代码是,一个被函数pullingCurrentStatus包裹的定时器,基于axios定时的向web接口发起请求,以实现轮询的需求。 无需过多的关注代码,因为没有业务场景,可能看的迷迷糊糊的。我只是在试图描述我遇到的问题。
现在,我这里有一个“退出队列”按钮,我期望当我点击改按钮,将触发“退出队列”按钮所绑定的方法,然后关闭上面的这个轮询。
可是,问题在于,定时器是被包裹在另一个函数中的局部变量,我怎么在另外的一个方法中去引用定时器变量呢? 引用不了,我就没办法去关闭它。
后来想到了一种办法,就是,通过在export default{data(){return{ TurnOffTheTimer:false }}}
设定一个全局的中间变量,这样,就可以实现在其他的地方关闭定时器了。其实蛮简单的,为了说明该方法,我写了下面这个demo,以供朋友们参考,也方便自己日后巩固学习之用。
vue
<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: "",
};
},
methods: {
startTheTimer(){
let BeijingTime = setInterval(()=>{
this.msg = new Date()
console.log(BeijingTime)
},1000)
},
turnOffTimer(){
// console.log("123")
}
}
};
</script>
在以上代码中,我们定义了一个定时器,每秒钟刷新一次当下时间,当点击“打开定时器”后,开始走时:
通同时,我们定义了一个关闭按钮,但是还没有执行任何操作。现在我们修改一下代码:
<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: "",
IfTurnOffTheTimer: false
};
},
methods: {
startTheTimer() {
let BeijingTime = setInterval(() => {
if (this.IfTurnOffTheTimer == true) {
clearInterval(BeijingTime);
}
this.msg = new Date();
}, 1000);
},
turnOffTimer() {
this.IfTurnOffTheTimer = true;
}
}
};
</script>
我们简单的修改了一些代码,在return里面新增了一个名为IfTurnOffTheTimer
的变量,并将其初始值设为false
,然后我们在定时器中增加了一个if判断,让他去判断变量IfTurnOffTheTimer
是否为 true,如果是,则销毁定时器。 最后,我们在turnOffTimer()
方法里,改变改变量的值为true
,这就基本上实现了我们的需求,解决了我们的问题。
当然,不难发现,是存在一些小问题的。
例如,我们发现当我们点击了“关闭定时器按钮”之后,再点“打开定时器”就没有反映了。这是当然了,因为 this.IfTurnOffTheTimer = true;
解决方法也很简单,在定时器之前,给它再赋值成false就行了。
startTheTimer() {
this.IfTurnOffTheTimer = false;
let BeijingTime = setInterval(() => {
if (this.IfTurnOffTheTimer == true) {
clearInterval(BeijingTime);
}
this.msg = new Date();
}, 1000);
},
此外,还有一个小问题,就是,我们发现带点击“关闭定时器”按钮之后,并不是立刻被销毁,而是总是会把定时器内代码执行完毕先,也就是this.msg = new Date();
这行代码总是会被执行一次。解决办法也简单,在它前面给他return
一下,让他停止执行,就可以了。
startTheTimer() {
this.IfTurnOffTheTimer = false;
let BeijingTime = setInterval(() => {
if (this.IfTurnOffTheTimer == true) {
clearInterval(BeijingTime);
return
}
this.msg = new Date();
}, 1000);
},