国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

項目中如何使用axios過(guò)濾多次重復請求詳解

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:峰峰會(huì )很好 欄目: JavaScript 歡迎投稿:712375056

目錄

    一、前言:

    我們在web應用開(kāi)發(fā)過(guò)程當中,經(jīng)常會(huì )遇到一個(gè)時(shí)刻發(fā)起了多個(gè)請求的場(chǎng)景

    這個(gè)情況下,我們通常的做法有兩種:

    • 可以在請求時(shí)show一個(gè)loading,阻止用戶(hù)操作。
    • 或者人為加個(gè)變量,做一個(gè)請求的節流

    我們的項目中,目前大部分情況也是采用以上兩種方式做的。今天來(lái)介紹一個(gè)新的方式。

    二、CancelToken類(lèi)

    我們之前實(shí)例化一個(gè)Promise,這個(gè)對象是否成功與否,是無(wú)法在函數外部決定的,這里邊使用要用到一個(gè)小竅門(mén),可以讓一個(gè)promise 和resolve分離。任何時(shí)機都可以觸發(fā)resolve:

      // 一個(gè)promise
      let resolvePromise
      let p = new Promise((resolve, reject) => {
        resolvePromise = resolve
      })
      // 這樣在外部執行
      resolvePromise()
    

    ok,有了這個(gè)前提,我們需要借助axios.CancelToken這個(gè)類(lèi)。

    這個(gè)類(lèi)相當于在每次請求的時(shí)候開(kāi)啟另一個(gè)promise和當前的請求形成一個(gè)promise.race(請求p1,取消請求p2),在promise中的resolve方法賦值給了一個(gè)外部的變量去接收。我們可以根據需求,人為決定是否取消前次請求。其實(shí)這就類(lèi)似,原來(lái)我們寫(xiě)fetch封裝接口超時(shí)的Promise.race類(lèi)似。

    cancelToken中也提供了相應的static方法source用來(lái)生成一個(gè)cancelToken和一個(gè)cancel方法其實(shí)就是這個(gè)promise的一個(gè)resolve。

        CancelToken.source = function source() {
        var cancel;
        // 
        var token = new CancelToken(function executor(c) {
            cancel = c;
        });
        return {
            token: token,
            cancel: cancel,
        };
    

    根據我們常用的的緩存方式,我們可以聲明一個(gè)map來(lái)存儲每次請求的url,同時(shí)存儲對應的cancel方法。

        // 聲明一個(gè)全局map
        const pendingHttp = new Map()
        // axios中內置的CancelToken類(lèi)
        const CancelToken = axios.CancelToken
           
        function addApi (config) {
          config.cancelToken = new CancelToken((cancel) => {
            const url = config.url
            console.log(pendingHttp)
            if (!pendingHttp.has(url)) {
              pendingHttp.set(url, cancel)
            }
          })
        }
    
        function cancelApi (config) {
          const url = config.url
          if (pendingHttp.has(url)) { // 如果在 pending 中存在當前請求標識,需要取消當前請求,并且移除
            const cancel = pendingHttp.get(url)
            cancel(url + '取消了')
            pendingHttp.delete(url) // 清空當前url的緩存
          }
        }
    
    • 要特殊注意,要想取消掉一個(gè)請求,需要在config上添加cancelToken這個(gè)屬性賦值為CancelToken的實(shí)例。否則cancel不掉。

    就像操作定時(shí)器一樣,要先嘗試取消上一次,然后再開(kāi)啟下一次

        httpService.interceptors.request.use(config => {
    
          cancelApi(config)
          addApi(config)
          
          // 本地調試的時(shí)候,是跨域的情況,加請求頭會(huì )有限制(此處是項目代碼無(wú)關(guān)緊要)
          const { headers = {} } = config; const { globalObj = {} } = window
          Object.assign(headers, globalObj, { from })
          
          return config
        }, error => {
          console.log(error)
          return Promise.reject(error)
        })
    

    然后還有一種可能性,第一次請求已經(jīng)返回了,又發(fā)起了相同的一次請求,所以在response里邊也要cancelApi一下。

        httpService.interceptors.response.use(
          response => {
            cancelApi(response.config)
            sentryCatchApi(response)
          },
          error => {
            // 請求超時(shí)
            if (error.message.includes('timeout')) { // 判斷請求異常信息中是否含有超時(shí)timeout字符串
              Toast.error({ text: '網(wǎng)頁(yè)請求超時(shí),請刷新重試~' })
            }
            sentryCatchApi(error)
            return Promise.reject(error)
          }
        )
    

    我們需要注意一點(diǎn),cancel其實(shí)就是resolve,我們cancel執行時(shí)候傳入的參數,會(huì )最終在response的error回調中,作為參數返回,這樣我們的捕捉錯誤的方法可能會(huì )有報錯。

        // 假設我們的error方法是這樣封裝的。 來(lái)看一下sentryCatchApi
        error => {
          sentryCatchApi(error)
          return Promise.reject(error)
        }
      // 由于這個(gè)方法需要接收一個(gè)對象,但是我們cancel取消請求的情況下,返回的是一個(gè)字符串,這時(shí)就報錯了。
      function sentryCatchApi (res) {
          try {
            res = res || {}
            const resData = res.data || {}
            Sentry.captureException(JSON.stringify(resData))
            console.log(`
              獲取數據失敗:
              請在瀏覽器中打開(kāi)進(jìn)入 webview的地址,并粘貼出來(lái),便于問(wèn)題排查
              :接口相關(guān)信息:
              接口地址:${res.config.url},
              接口返回值:code:${resData.code},
              message:${resData.message},
              data:${JSON.stringify(resData.data)}
            `)
          } catch (err) {
            console.error(err)
          }
        }
    

    需要使用isCancel這個(gè)api

       error => {
        if (axios.isCancel(error)) return console.log('請求被取消了', error.message)
        sentryCatchApi(error)
        return Promise.reject(error)
      }
    

    最終效果

    控制臺也沒(méi)有任何報錯啦。(后續完善到項目中)

    總結

    到此這篇關(guān)于項目中如何使用axios過(guò)濾多次重復請求的文章就介紹到這了,更多相關(guān)axios過(guò)濾多次重復請求內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

    国产福利在线观看片| 放荡少妇深喉吞浓精| 欧美乱妇高清无乱码| 日日碰日日摸日日澡视频播放| 日韩成人影片| 人妻夜夜添夜夜无码AV|