




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第JavaScript實(shí)現(xiàn)可終止輪詢(xún)請(qǐng)求的方法目錄什么是輪詢(xún)請(qǐng)求?輪詢(xún)的要點(diǎn)setInterval的問(wèn)題實(shí)現(xiàn)輪詢(xún)準(zhǔn)備工作基礎(chǔ)版進(jìn)階版最終版最近遇到了一個(gè)需求,需要每隔5s請(qǐng)求一個(gè)接口獲取接口返回的結(jié)果,返回成功后停止請(qǐng)求,接口的返回的值有下面幾種情況:
//成功
"code":0,
"msg":'成功'
//查詢(xún)中
"code":-1,
"msg":'結(jié)果查詢(xún)中'
//失敗
"code":1,
"msg":'返回結(jié)果失敗'
}
code是接口的狀態(tài)碼,為0的時(shí)候表示接口返回的成功,這時(shí)就不需要再請(qǐng)求接口。
實(shí)現(xiàn)這種需求首先想到的就是用輪詢(xún)?nèi)プ隽恕?/p>
什么是輪詢(xún)請(qǐng)求?
通俗地說(shuō),輪詢(xún)請(qǐng)求就是間隔相同的時(shí)間(如5s)后不斷地向服務(wù)端發(fā)起同一個(gè)接口的請(qǐng)求,當(dāng)然不能無(wú)限次去請(qǐng)求,所以輪詢(xún)必須要有個(gè)停止輪詢(xún)的機(jī)制
輪詢(xún)的要點(diǎn)
1.按照需要選擇是否立即發(fā)起請(qǐng)求再進(jìn)入輪詢(xún)
2.上一次的請(qǐng)求響應(yīng)后到了指定的時(shí)間間隔后再繼續(xù)執(zhí)行下一次請(qǐng)求
3.當(dāng)輪詢(xún)的請(qǐng)求發(fā)生報(bào)錯(cuò)的時(shí)候應(yīng)該停止輪詢(xún)
4.被停止的輪詢(xún)可以根據(jù)需要再次發(fā)起輪詢(xún)
setInterval的問(wèn)題
因?yàn)槭遣粩嗾?qǐng)求,所以首先能想到的就是用setInterval去實(shí)現(xiàn),但是setInterval做輪詢(xún)的話,會(huì)有以下嚴(yán)重的問(wèn)題
1.即使調(diào)用的代碼報(bào)錯(cuò)了,setInterval會(huì)持續(xù)的調(diào)用
2.setInterval不會(huì)等到上一次的請(qǐng)求響應(yīng)后再執(zhí)行,只要到了指定的時(shí)間間隔就會(huì)執(zhí)行,哪怕有報(bào)錯(cuò)也會(huì)執(zhí)行
3.setInterval定時(shí)不準(zhǔn)確,這個(gè)跟事件循環(huán)有關(guān),這里不展開(kāi)啦~
實(shí)現(xiàn)輪詢(xún)
實(shí)現(xiàn)輪詢(xún),只要按照輪詢(xún)的要點(diǎn)去實(shí)現(xiàn)一個(gè)setInterval方法就可以了,下面用setTimeout一步步去實(shí)現(xiàn)這個(gè)方法
準(zhǔn)備工作
首先準(zhǔn)備一個(gè)html模板,這個(gè)模板包含兩個(gè)按鈕,一個(gè)開(kāi)啟輪詢(xún),一個(gè)停止輪詢(xún),輪詢(xún)的方法命名為myInterval,返回一個(gè)start和stop方法用于開(kāi)始和停止輪詢(xún)
!DOCTYPEhtml
htmllang="en"
head
metacharset="UTF-8"/
metahttp-equiv="X-UA-Compatible"content="IE=edge"/
metaname="viewport"content="width=device-width,initial-scale=1.0"/
titleDocument/title
/head
body
buttonid="start"開(kāi)始/button
buttonid="stop"停止/button
/body
/html
script
conststartBtn=document.getElementById('start')
conststopBtn=document.getElementById('stop')
//輪詢(xún)?cè)谶@
functionmyInterval(){
return{
start:()={},
stop:()={}
//輪詢(xún)管理器
constintervalManager=myInterval(main)
//輪詢(xún)的方法
letcount=0
functionmain(){
count+=1
console.log('執(zhí)行:',count)
startBtn.addEventListener('click',intervalManager.start)
stopBtn.addEventListener('click',intervalManager.stop)
/script
基礎(chǔ)版
functionmyInterval(callback,interval=2000){
lettimerId
constloop=async()={
callback()
return(timer=setTimeout(loop,interval))
return{
start:()={
loop()
stop:()={
console.log('停止執(zhí)行')
clearTimeout(timerId)
}
這個(gè)版本基本跟setInterval的功能一致了,只不過(guò)執(zhí)行需要手動(dòng)調(diào)用start,停止要調(diào)用stop。
一個(gè)常見(jiàn)的場(chǎng)景是,當(dāng)輪詢(xún)執(zhí)行n次后,停止輪詢(xún),下面改一下main方法,等count等于5的時(shí)候停止輪詢(xún)
functionmain(){
count+=1
console.log('執(zhí)行:',count)
if(count==5){
count=0
intervalManager.stop()
}
發(fā)現(xiàn)當(dāng)count等于5時(shí),確實(shí)調(diào)用了stop方法,但是卻沒(méi)有停止輪詢(xún),當(dāng)點(diǎn)擊停止按鈕的時(shí)候,又停止了輪詢(xún),這是什么情況呢?
看一下loop方法
constloop=async()={
callback()
return(timerId=setTimeout(()={
loop()
},interval))
}
因?yàn)槭窃赾allback中執(zhí)行stop的,stop并沒(méi)有阻止定時(shí)器中回調(diào)(loop)的執(zhí)行,所以看起來(lái)是停止了,但是新的定時(shí)器還是開(kāi)啟了
進(jìn)階版
解決基礎(chǔ)版無(wú)法自動(dòng)停止的問(wèn)題也很簡(jiǎn)單,加一個(gè)變量來(lái)檢測(cè),一旦執(zhí)行了stop方法不返回定時(shí)器就可以了
//可以自動(dòng)停止的定時(shí)器
functionmyInterval(callback,interval=2000){
lettimer
letisStop=false
conststop=()={
console.log('停止')
isStop=true
clearTimeout(timer)
conststart=()={
isStop=false
loop()
constloop=async()={
callback()
if(isStop)return
return(timer=setTimeout(loop,interval))
return{
start,
stop
}
下面把main方法再改一改
functionmain(){
constflag=parseInt(Math.random()*2)===1
console.log('flag',flag)
returnflagPromise.resolve():Promise.reject()
}
main方法這次返回的是Promise,我們來(lái)看看執(zhí)行的情況
進(jìn)階版還是不支持main中有Promise的情況,我們希望的是,當(dāng)main中出現(xiàn)Promisereject和錯(cuò)誤的時(shí)候,中止輪詢(xún)
最終版
用async和await可以實(shí)現(xiàn)main方法中出現(xiàn)錯(cuò)誤的時(shí)候中止輪詢(xún)
functionmyInterval(callback,interval=2000){
lettimer
letisStop=false
conststop=()={
console.log('停止')
isStop=true
clearTimeout(timer)
conststart=async()={
isStop=false
awaitloop()
constloop=async()={
try{
awaitcallback(stop)
}catch(err){
console.error('輪詢(xún)出錯(cuò):',err)
thrownewError('輪詢(xún)出錯(cuò):',err)
if(isStop)return
return(timer=setTimeout(loop,interval))
return{
start,
stop
}
可以看到最終版能滿足我們的輪詢(xún)要求了,遇到接口報(bào)錯(cuò)的時(shí)候可以終止請(qǐng)求,細(xì)心的您應(yīng)該能發(fā)現(xiàn)這行代碼callback(stop),是的,main中現(xiàn)在多了一個(gè)回調(diào)方法,可以直接調(diào)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)徒合同協(xié)議書(shū)百度庫(kù)
- 經(jīng)濟(jì)學(xué)微觀試題及答案
- 合同權(quán)益轉(zhuǎn)讓協(xié)議書(shū)
- 釘釘項(xiàng)目管理試題及答案
- 出售合同協(xié)議書(shū)
- 貨源合同協(xié)議書(shū)
- 校車(chē)轉(zhuǎn)讓合同協(xié)議書(shū)范本
- 租憑農(nóng)田合同協(xié)議書(shū)
- 租地合同協(xié)議書(shū)廣告
- 代理協(xié)議書(shū)和合同
- 跨學(xué)科實(shí)踐;自行車(chē)-2024-2025學(xué)年教科版物理八年級(jí)下冊(cè)教學(xué)同步課件
- 輔助運(yùn)輸管理規(guī)定
- 康復(fù)治療士測(cè)試題及答案
- 漢語(yǔ)言文學(xué)自考命題形式試題及答案
- 中國(guó)創(chuàng)新藥械多元支付白皮書(shū)2025
- 2025-2030中國(guó)光芯片行業(yè)市場(chǎng)發(fā)展現(xiàn)狀及競(jìng)爭(zhēng)格局研究報(bào)告
- 《工業(yè)機(jī)器人仿真技術(shù)應(yīng)用》課件-項(xiàng)目四 工業(yè)機(jī)器人涂膠工作站的仿真應(yīng)用
- 2016賦安消防JB-QBH-FS5101W 火災(zāi)報(bào)警控制器
- 2025-2030年中國(guó)泵閥產(chǎn)業(yè)運(yùn)行狀況及發(fā)展前景分析報(bào)告
- 中醫(yī)養(yǎng)生學(xué)沐浴養(yǎng)生講解
- CNAS-GL040-2019 儀器驗(yàn)證實(shí)施指南
評(píng)論
0/150
提交評(píng)論