欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)可終止輪詢請(qǐng)求的方法

 更新時(shí)間:2022年06月14日 09:58:44   作者:黑化程序員  
輪詢請(qǐng)求就是間隔相同的時(shí)間(如5s)后不斷地向服務(wù)端發(fā)起同一個(gè)接口的請(qǐng)求,當(dāng)然不能無限次去請(qǐng)求,所以輪詢必須要有個(gè)停止輪詢的機(jī)制,今天通過本文給大家介紹JavaScript實(shí)現(xiàn)可終止的輪詢請(qǐng)求,感興趣的朋友一起看看吧

最近遇到了一個(gè)需求,需要每隔5s請(qǐng)求一個(gè)接口獲取接口返回的結(jié)果,返回成功后停止請(qǐng)求,接口的返回的值有下面幾種情況:

// 成功
{
    "code": 0,
    "msg": '成功'
}
// 查詢中
{
    "code": -1,
    "msg": '結(jié)果查詢中'
}
// 失敗
{
    "code": 1,
    "msg": '返回結(jié)果失敗'
}

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

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

什么是輪詢請(qǐng)求?

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

輪詢的要點(diǎn)

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

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

3. 當(dāng)輪詢的請(qǐng)求發(fā)生報(bào)錯(cuò)的時(shí)候應(yīng)該停止輪詢

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

setInterval的問題

因?yàn)槭遣粩嗾?qǐng)求,所以首先能想到的就是用setInterval去實(shí)現(xiàn),但是setInterval做輪詢的話,會(huì)有以下嚴(yá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),這里不展開啦~

實(shí)現(xiàn)輪詢

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

準(zhǔn)備工作

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

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="start">開始</button>
    <button id="stop">停止</button>
  </body>
</html>
<script>
  const startBtn = document.getElementById('start')
  const stopBtn = document.getElementById('stop')
  
  // 輪詢?cè)谶@
  function myInterval() {
      return {
          start: () => {},
          stop: () => {}
      }
  }
  
  // 輪詢管理器
  const intervalManager = myInterval(main)
  
  // 輪詢的方法
  let count = 0
  function main() {
    count += 1
    console.log('執(zhí)行:', count)
  }
  
  startBtn.addEventListener('click', intervalManager.start)
  stopBtn.addEventListener('click', intervalManager.stop)
</script>

基礎(chǔ)版

function myInterval(callback, interval = 2000) {
    let timerId
    const loop = async () => {
      callback()
      return (timer = setTimeout(loop, interval))
    }
    return {
      start: () => {
        loop()
      },
      stop: () => {
        console.log('停止執(zhí)行')
        clearTimeout(timerId)
      }
    }
  }

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

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

function main() {
    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方法,但是卻沒有停止輪詢,當(dāng)點(diǎn)擊停止按鈕的時(shí)候,又停止了輪詢,這是什么情況呢?

看一下loop方法

const loop = async () => {
  callback()
  return (timerId = setTimeout(() => {
    loop()
  }, interval))
}

因?yàn)槭窃?code>callback中執(zhí)行stop的,stop并沒有阻止定時(shí)器中回調(diào)(loop)的執(zhí)行,所以看起來是停止了,但是新的定時(shí)器還是開啟了

進(jìn)階版

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

// 可以自動(dòng)停止的定時(shí)器
function myInterval(callback, interval = 2000) {
    let timer
    let isStop = false
    const stop = () => {
      console.log('停止')
      isStop = true
      clearTimeout(timer)
    }
    const start = () => {
      isStop = false
      loop()
    }
    const loop = async () => {
      callback()
      if (isStop) return
      return (timer = setTimeout(loop, interval))
    }
    return {
      start,
      stop
    }
  }

下面把main方法再改一改

function main() {
    const flag = parseInt(Math.random() * 2) === 1
    console.log('flag', flag)
    return flag ? Promise.resolve() : Promise.reject()
}

main方法這次返回的是Promise,我們來看看執(zhí)行的情況

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

最終版

asyncawait可以實(shí)現(xiàn)main方法中出現(xiàn)錯(cuò)誤的時(shí)候中止輪詢

function myInterval(callback, interval = 2000) {
    let timer
    let isStop = false
    const stop = () => {
      console.log('停止')
      isStop = true
      clearTimeout(timer)
    }
    const start = async () => {
      isStop = false
      await loop()
    }
    const loop = async () => {
      try {
        await callback(stop)
      } catch (err) {
        console.error('輪詢出錯(cuò):', err)
        throw new Error('輪詢出錯(cuò):', err)
      }
      if (isStop) return
      return (timer = setTimeout(loop, interval))
    }
    return {
      start,
      stop
    }
  }

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

main再次改回來

let count = 0
function main(stop) {
    count += 1
    console.log('count:', count)
    if (count == 5) {
      stop()
    }
}

可以看到,調(diào)用stop也是可以中止輪詢的

現(xiàn)在一個(gè)完美的js可終止輪詢請(qǐng)求,interval就完成啦~

到此這篇關(guān)于用JavaScript實(shí)現(xiàn)可終止的輪詢請(qǐng)求的文章就介紹到這了,更多相關(guān)js輪詢請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js TextArea的選中區(qū)域處理

    js TextArea的選中區(qū)域處理

    js中對(duì)于TextArea的選中區(qū)域后進(jìn)行處理的代碼,需要的朋友可以參考下。
    2010-12-12
  • JavaScript中setInterval的用法總結(jié)

    JavaScript中setInterval的用法總結(jié)

    這篇文章主要是對(duì)JavaScript中setInterval的用法進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-11-11
  • js實(shí)現(xiàn)隨機(jī)點(diǎn)名功能

    js實(shí)現(xiàn)隨機(jī)點(diǎn)名功能

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)隨機(jī)點(diǎn)名功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • js multiple全選與取消全選實(shí)現(xiàn)代碼

    js multiple全選與取消全選實(shí)現(xiàn)代碼

    本文章總結(jié)了利用jquery與js實(shí)現(xiàn)multiple全選與取消全選代碼有需要參考的朋友可參考下
    2012-12-12
  • JavaScript正則表達(dá)式和級(jí)聯(lián)效果

    JavaScript正則表達(dá)式和級(jí)聯(lián)效果

    正則表達(dá)式(regular expression)是一種字符串匹配的模式,用來檢查一個(gè)字符串中是否包含指定模式的字符串。下面通過本文給大家分享JavaScript_正則表達(dá)式和級(jí)聯(lián)效果,感興趣的朋友一起看看吧
    2017-09-09
  • JS判斷元素是否在可視區(qū)域技巧詳解

    JS判斷元素是否在可視區(qū)域技巧詳解

    這篇文章主要為大家介紹了JS判斷元素是否在可視區(qū)域技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 微信小程序開發(fā)之全局配置與頁面配置實(shí)現(xiàn)

    微信小程序開發(fā)之全局配置與頁面配置實(shí)現(xiàn)

    本文主要介紹了微信小程序開發(fā)之全局配置與頁面配置實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • js操作CheckBoxList實(shí)現(xiàn)全選/反選(在客服端完成)

    js操作CheckBoxList實(shí)現(xiàn)全選/反選(在客服端完成)

    對(duì)于CheckBoxList控件來說,一方面要實(shí)現(xiàn)大量數(shù)據(jù)在服務(wù)器端的綁定工作,另一方面往往要求實(shí)現(xiàn)全選、反選等功能,接下來將介紹js操作CheckBoxList實(shí)現(xiàn)全選/反選,感興趣的朋友可以了解下,或許對(duì)你有所幫助
    2013-02-02
  • javascript檢測(cè)移動(dòng)設(shè)備橫豎屏

    javascript檢測(cè)移動(dòng)設(shè)備橫豎屏

    移動(dòng)端的開發(fā)過程中,免不了要判斷橫豎屏,然后在執(zhí)行其他操作,比如分別加載不同樣式,橫屏顯示某些內(nèi)容,豎屏顯示其他內(nèi)容等等。
    2016-05-05
  • JavaScript中常見內(nèi)置函數(shù)用法示例

    JavaScript中常見內(nèi)置函數(shù)用法示例

    這篇文章主要介紹了JavaScript中常見內(nèi)置函數(shù)用法,結(jié)合實(shí)例形式分析了JavaScript常用內(nèi)置函數(shù)的功能、參數(shù)、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-05-05

最新評(píng)論