JavaScript實現(xiàn)可終止輪詢請求的方法_第1頁
JavaScript實現(xiàn)可終止輪詢請求的方法_第2頁
JavaScript實現(xiàn)可終止輪詢請求的方法_第3頁
JavaScript實現(xiàn)可終止輪詢請求的方法_第4頁
JavaScript實現(xiàn)可終止輪詢請求的方法_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第JavaScript實現(xiàn)可終止輪詢請求的方法目錄什么是輪詢請求?輪詢的要點setInterval的問題實現(xiàn)輪詢準(zhǔn)備工作基礎(chǔ)版進(jìn)階版最終版最近遇到了一個需求,需要每隔5s請求一個接口獲取接口返回的結(jié)果,返回成功后停止請求,接口的返回的值有下面幾種情況:

//成功

"code":0,

"msg":'成功'

//查詢中

"code":-1,

"msg":'結(jié)果查詢中'

//失敗

"code":1,

"msg":'返回結(jié)果失敗'

}

code是接口的狀態(tài)碼,為0的時候表示接口返回的成功,這時就不需要再請求接口。

實現(xiàn)這種需求首先想到的就是用輪詢?nèi)プ隽恕?/p>

什么是輪詢請求?

通俗地說,輪詢請求就是間隔相同的時間(如5s)后不斷地向服務(wù)端發(fā)起同一個接口的請求,當(dāng)然不能無限次去請求,所以輪詢必須要有個停止輪詢的機(jī)制

輪詢的要點

1.按照需要選擇是否立即發(fā)起請求再進(jìn)入輪詢

2.上一次的請求響應(yīng)后到了指定的時間間隔后再繼續(xù)執(zhí)行下一次請求

3.當(dāng)輪詢的請求發(fā)生報錯的時候應(yīng)該停止輪詢

4.被停止的輪詢可以根據(jù)需要再次發(fā)起輪詢

setInterval的問題

因為是不斷請求,所以首先能想到的就是用setInterval去實現(xiàn),但是setInterval做輪詢的話,會有以下嚴(yán)重的問題

1.即使調(diào)用的代碼報錯了,setInterval會持續(xù)的調(diào)用

2.setInterval不會等到上一次的請求響應(yīng)后再執(zhí)行,只要到了指定的時間間隔就會執(zhí)行,哪怕有報錯也會執(zhí)行

3.setInterval定時不準(zhǔn)確,這個跟事件循環(huán)有關(guān),這里不展開啦~

實現(xiàn)輪詢

實現(xiàn)輪詢,只要按照輪詢的要點去實現(xiàn)一個setInterval方法就可以了,下面用setTimeout一步步去實現(xiàn)這個方法

準(zhǔn)備工作

首先準(zhǔn)備一個html模板,這個模板包含兩個按鈕,一個開啟輪詢,一個停止輪詢,輪詢的方法命名為myInterval,返回一個start和stop方法用于開始和停止輪詢

!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"開始/button

buttonid="stop"停止/button

/body

/html

script

conststartBtn=document.getElementById('start')

conststopBtn=document.getElementById('stop')

//輪詢在這

functionmyInterval(){

return{

start:()={},

stop:()={}

//輪詢管理器

constintervalManager=myInterval(main)

//輪詢的方法

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)

}

這個版本基本跟setInterval的功能一致了,只不過執(zhí)行需要手動調(diào)用start,停止要調(diào)用stop。

一個常見的場景是,當(dāng)輪詢執(zhí)行n次后,停止輪詢,下面改一下main方法,等count等于5的時候停止輪詢

functionmain(){

count+=1

console.log('執(zhí)行:',count)

if(count==5){

count=0

intervalManager.stop()

}

發(fā)現(xiàn)當(dāng)count等于5時,確實調(diào)用了stop方法,但是卻沒有停止輪詢,當(dāng)點擊停止按鈕的時候,又停止了輪詢,這是什么情況呢?

看一下loop方法

constloop=async()={

callback()

return(timerId=setTimeout(()={

loop()

},interval))

}

因為是在callback中執(zhí)行stop的,stop并沒有阻止定時器中回調(diào)(loop)的執(zhí)行,所以看起來是停止了,但是新的定時器還是開啟了

進(jìn)階版

解決基礎(chǔ)版無法自動停止的問題也很簡單,加一個變量來檢測,一旦執(zhí)行了stop方法不返回定時器就可以了

//可以自動停止的定時器

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,我們來看看執(zhí)行的情況

進(jìn)階版還是不支持main中有Promise的情況,我們希望的是,當(dāng)main中出現(xiàn)Promisereject和錯誤的時候,中止輪詢

最終版

用async和await可以實現(xiàn)main方法中出現(xià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('輪詢出錯:',err)

thrownewError('輪詢出錯:',err)

if(isStop)return

return(timer=setTimeout(loop,interval))

return{

start,

stop

}

可以看到最終版能滿足我們的輪詢要求了,遇到接口報錯的時候可以終止請求,細(xì)心的您應(yīng)該能發(fā)現(xiàn)這行代碼callback(stop),是的,main中現(xiàn)在多了一個回調(diào)方法,可以直接調(diào)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論