項(xiàng)目背景
幫同學(xué)課設(shè)做實(shí)時(shí)數(shù)據(jù)展示入偷,同學(xué)后端數(shù)據(jù)是檢測(cè)實(shí)時(shí)的充電樁電流疏之,電壓等參數(shù)暇咆,然后以折線圖和表格的形式實(shí)時(shí)展示到前端界面丙曙,因?yàn)樗麤](méi)有用websocket的連接方式給我數(shù)據(jù)亏镰,所以我要用比較落后原始的每隔一定時(shí)間發(fā)起一個(gè)請(qǐng)求的方式做到實(shí)時(shí)展示數(shù)據(jù)
項(xiàng)目展示
github地址:這里!這里!
入坑
一般做實(shí)時(shí)數(shù)據(jù)請(qǐng)求不采用websocket的話拯爽,而使用輪詢的請(qǐng)求有兩種方式,即:
setInterval(function(){方法}, 2000)
這種方法是每過(guò)兩秒就自動(dòng)創(chuàng)建一個(gè)異步操作請(qǐng)求數(shù)據(jù)逼肯,不管是DOM渲染延遲還是網(wǎng)絡(luò)堵塞桃煎,都會(huì)持續(xù)每隔2秒時(shí)間去請(qǐng)求,頗有種“我只管定時(shí)請(qǐng)求为迈,哪管它洪水滔天”的味道,所以這個(gè)坑我一開始就放棄了
setTimeout(function(){方法}, 2000)
這種方法是方法里面設(shè)置一個(gè)定時(shí)器搜锰,2秒后執(zhí)行耿战,然后繼續(xù)在定時(shí)器里面繼續(xù)執(zhí)行本身,有點(diǎn)遞歸的味道昆箕,不過(guò)只有傳遞,沒(méi)有回歸的遞歸鹏倘,因?yàn)榭紤]到dom重新渲染和網(wǎng)絡(luò)延遲的問(wèn)題,我就用了這個(gè)方法
踩坑
當(dāng)我用setTimeout(function(){方法}, 2000)
方法后骆姐,我發(fā)現(xiàn)剛開始還是好的,折線圖每隔2S數(shù)據(jù)自動(dòng)刷新一次玻褪,后面我再切換充電樁的時(shí)候它就會(huì)數(shù)據(jù)刷新變快公荧,多次點(diǎn)擊后就變成了折線圖會(huì)一秒刷新好幾次
后來(lái)我在devtools中尋找原因的時(shí)候,發(fā)現(xiàn)當(dāng)我切換充電樁后窟社,就會(huì)多開啟一個(gè)請(qǐng)求:簡(jiǎn)單來(lái)講就是我點(diǎn)擊“充電樁1”,他是會(huì)每隔2秒發(fā)起對(duì)一個(gè)充電樁1的數(shù)據(jù)請(qǐng)求灿里,然后我點(diǎn)擊“充電樁2”,他每隔2秒發(fā)起兩個(gè)對(duì)充電樁2的數(shù)據(jù)請(qǐng)求儒拂,我再點(diǎn)擊回“充電樁1”色鸳,他就每隔2秒發(fā)起三個(gè)對(duì)充電樁1的數(shù)據(jù)請(qǐng)求,再點(diǎn)再加……
請(qǐng)求對(duì)象是對(duì)的褥影,但是點(diǎn)擊一次會(huì)多一個(gè)網(wǎng)絡(luò)請(qǐng)求池户,后面也就造成了數(shù)據(jù)刷新很快,如果2秒請(qǐng)求4次就相當(dāng)于0.5秒刷新一次
填坑
這里出現(xiàn)了一種假象赊抖,也就是我每點(diǎn)擊一次氛雪,好像就增加了一個(gè)線程耸成,然后共同執(zhí)行請(qǐng)求,但是JavaScript是單線程的
axios請(qǐng)求和ajax一樣都是異步執(zhí)行井氢,也就是在主線程同步任務(wù)執(zhí)行完畢后執(zhí)行axios內(nèi)部的回調(diào)函數(shù),setTimeout()
的方法也是異步執(zhí)行的劲件,所以又進(jìn)入等待隊(duì)列约急,axios內(nèi)部執(zhí)行完后再?gòu)漠惒饺蝿?wù)隊(duì)列中執(zhí)行setTimeout()
的函數(shù),然后我每次切換充電樁的時(shí)候牵辣,產(chǎn)生一次點(diǎn)擊事件奴饮,setTimeout()
內(nèi)部又獨(dú)立出了一個(gè)setTimeout()
,再點(diǎn)擊再出現(xiàn)一個(gè)供填,跟細(xì)胞分裂一樣
出坑
emmmm……
其實(shí)解決方案很簡(jiǎn)單:
在vue的data中設(shè)置一個(gè)標(biāo)志位
let id=setTimeout()近她;
this.timeTag = a;
然后在方法開頭
clearTimeout(this.timeTag);
咳咳……就是這么簡(jiǎn)單