vue項(xiàng)目開(kāi)發(fā)中setTimeout等定時(shí)器的管理問(wèn)題
一、問(wèn)題來(lái)源。
在項(xiàng)目中,我們經(jīng)常有這樣的需求,一個(gè)頁(yè)面初始化后,需要不斷的去請(qǐng)求后端,來(lái)獲取當(dāng)前某個(gè)記錄的最新?tīng)顟B(tài)。
顯然,這個(gè)可以用setTimeout以及回調(diào)中繼續(xù)setTimeout來(lái)實(shí)現(xiàn)。
我們假設(shè)定時(shí)器是在頁(yè)面#/test/aaa上創(chuàng)建的。
但是,會(huì)遇到以下兩個(gè)問(wèn)題,我從#/test/aaa 這個(gè)頁(yè)面切換到 #/test/bbb頁(yè)面后如果停留在#/test/bbb,定時(shí)器還在跑。
其次,如果我不斷在#/test/aaa 和 #/test/bbb兩個(gè)頁(yè)面之間不斷的切換,而且切換時(shí)間小于定時(shí)器的間隔時(shí)間時(shí),也會(huì)出現(xiàn)
重復(fù)創(chuàng)建setTimeout的情況。
現(xiàn)在的問(wèn)題就是,我們?nèi)绾巫龅焦芾矶〞r(shí)器。
二、示例代碼。
created() { if ( this.timeOut ) { clearTimeout(this.timeOut); } this.getListIng(); }, computed: { timeOut: { set (val) { this.$store.state.timeout.compileTimeout = val; }, get() { return this.$store.state.timeout.compileTimeout; } }, }, methods: { getListIng() { // 這里是一個(gè)http的異步請(qǐng)求 if ( getUrlModule() == 'aaa' ) { let _this = this; this.timeOut = setTimeout(() => { _this.getListIng(); }, 5000); } else { this.timeOut = ''; } }, }
(1)如上面代碼所示,當(dāng)創(chuàng)建頁(yè)面(created執(zhí)行)時(shí),會(huì)先判斷變量this.timeOut是否存在,如果存在,先clearTimeout掉。
(2)而,this.timeOut這個(gè)變量對(duì)應(yīng)的是全局store里的this.$store.state.timeout.compileTimeout
。并且是雙向綁定的,這個(gè)
請(qǐng)自行搜索vue2.0中computed用法。
(3)在我們的主函數(shù)getListIng()中,會(huì)先使用函數(shù)getUrlModule()根據(jù)url判斷當(dāng)前頁(yè)面是否是aaa頁(yè)面,如果是的,就執(zhí)行setTimeOut,
如果不是,就不行執(zhí)行了,并且設(shè)置this.timeOut = '';
我們假設(shè)上面沒(méi)有if ( getUrlModule() == 'aaa' )
這句判斷,會(huì)出現(xiàn),當(dāng)我們已經(jīng)跳出了當(dāng)前aaa頁(yè)面,去了bbb頁(yè)面并且一直停留在bbb頁(yè)面時(shí),
還有setTimeout在執(zhí)行,就會(huì)不斷有http的請(qǐng)求。
如果沒(méi)有if ( this.timeOut ) { clearTimeout(this.timeOut); }
這句代碼。當(dāng)我們不斷在2個(gè)頁(yè)面之間切換時(shí),且切換的頻率很高。會(huì)出現(xiàn)多次創(chuàng)建
setTimeout的情況。這個(gè)邏輯稍微有點(diǎn)繞,請(qǐng)閱讀者自行演算。
三、我們必須清楚的事實(shí)。
(1)vue中$store里創(chuàng)建的變量,其實(shí)是全局變量,這個(gè)變量在切換頁(yè)面時(shí)不會(huì)清除,當(dāng)我們刷新頁(yè)面時(shí)會(huì)清除掉。
(2)在前端頁(yè)面中,當(dāng)我們刷新頁(yè)面時(shí),會(huì)將當(dāng)前頁(yè)面之前創(chuàng)建的setTimeout以及其他定時(shí)器都清除掉。但是,切換頁(yè)面(僅僅是路由切換)
是不會(huì)清除的。
(3)setTimeout、setinterval有本質(zhì)的不同,前者只執(zhí)行一次,除非你在回調(diào)中,不斷的調(diào)用,而后者是不間斷調(diào)用的。但是,我在各種實(shí)踐中發(fā)現(xiàn),
還是setTimeout好用。因?yàn)?,setTimeout可以根據(jù)條件,及時(shí)在回調(diào)中停用。如果采用setinterval,我們很有可能捕捉不到停用的條件而無(wú)法停用。
補(bǔ)充:Vue之SetTimeout
1.前言
相信很多人都遇到過(guò)這樣的問(wèn)題,頁(yè)面數(shù)據(jù)需要不斷的刷新,也就是不斷的發(fā)送ajax請(qǐng)求來(lái)更新數(shù)據(jù),那么在vue中怎樣做才比較好呢?這里介紹一下我踩的坑,以及解決方案
2.問(wèn)題
settimeout用來(lái)調(diào)用請(qǐng)求數(shù)據(jù),但是我遇到的問(wèn)題就是,沒(méi)有用合適的方式去關(guān)閉settimeout,出現(xiàn)了離開(kāi)當(dāng)前頁(yè)面,請(qǐng)求還在不斷的發(fā)送問(wèn)題,這樣給服務(wù)器帶來(lái)了無(wú)必要的壓力。附上之前的代碼:
self.deployTimeOutId = setTimeout(() => { self.getDeployList(false); }, 5000);
說(shuō)明:這一段代碼是嵌在getDeployList方法中的,離開(kāi)當(dāng)前頁(yè)面的是時(shí)候,必須要去手動(dòng)的把這個(gè)settimeout清除才行。一般這個(gè)寫(xiě)在destoryed()這個(gè)鉤子里。
window.clearTimeout(this.deployTimeOutId);
雖然這樣處理了,但在邏輯比較復(fù)雜的情況下,還是出現(xiàn)了沒(méi)有關(guān)閉的情況,而且排查起來(lái)很痛苦。下面介紹一種針對(duì)Vue比較好的做法。
3.解決方案
let self=this; if (self && !self._isDestroyed) { setTimeout(() => { if (self && !self._isDestroyed) self.getDeployList(); }, 5000); }
_isDestroyed這個(gè)屬性表示的是當(dāng)前這個(gè)組件是否有被銷毀,true表示當(dāng)前的組件已經(jīng)被銷毀,通過(guò)上面這個(gè)判斷,我們就不需要自己手動(dòng)的去用ID來(lái)清除了,這個(gè)就相當(dāng)于遞歸嘛,有了一個(gè)結(jié)束判斷,避免了死循環(huán)咯~~
總結(jié)
以上所述是小編給大家介紹的vue項(xiàng)目開(kāi)發(fā)中setTimeout等定時(shí)器的管理問(wèn)題,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)
給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明
這篇文章主要介紹了vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04vue設(shè)置路由title,但刷新頁(yè)面時(shí)title失效的解決
這篇文章主要介紹了vue設(shè)置路由title,但刷新頁(yè)面時(shí)title失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06使用vue2.0創(chuàng)建的項(xiàng)目的步驟方法
這篇文章主要介紹了使用vue2.0創(chuàng)建的項(xiàng)目的步驟方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue3中watch監(jiān)聽(tīng)的四種寫(xiě)法
本文主要介紹了vue3中watch監(jiān)聽(tīng)的四種寫(xiě)法,包含了ref 定義的數(shù)據(jù),reactive定義的數(shù)據(jù),函數(shù)返回的值(getter函數(shù))和前面3個(gè)內(nèi)容的數(shù)組,具有一定的參考價(jià)值,感興趣的可以了了解一下2024-02-02簡(jiǎn)單談?wù)刅ue 模板各類數(shù)據(jù)綁定
Vue.js 的模板是基于 DOM 實(shí)現(xiàn)的。這意味著所有的 Vue.js 模板都是可解析的有效的 HTML,且通過(guò)一些特殊的特性做了增強(qiáng)。Vue 模板因而從根本上不同于基于字符串的模板,請(qǐng)記住這點(diǎn)。2016-09-09Vue.js3.2的vnode部分優(yōu)化升級(jí)使用示例詳解
這篇文章主要為大家介紹了Vue.js3.2的vnode部分優(yōu)化升級(jí)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Vue+Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖
這篇文章主要為大家詳細(xì)介紹了Vue如何結(jié)合Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03