今天在開發中,遇到了這樣一種場景。
有兩個功能按鈕:“申請排隊”、“退出隊列”,點擊“申請排隊”,將觸發被一個名為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>