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

淺談axios中取消請(qǐng)求及阻止重復(fù)請(qǐng)求的方法

 更新時(shí)間:2022年02月15日 10:06:31   作者:harsima  
在實(shí)際項(xiàng)目中,我們可能需要對(duì)請(qǐng)求進(jìn)行“防抖”處理。本文主要實(shí)現(xiàn)axios中取消請(qǐng)求及阻止重復(fù)請(qǐng)求,具有一定的參考價(jià)值,感興趣的可以了解一下

前言

在實(shí)際項(xiàng)目中,我們可能需要對(duì)請(qǐng)求進(jìn)行“防抖”處理。這里主要是為了阻止用戶在某些情況下短時(shí)間內(nèi)重復(fù)點(diǎn)擊某個(gè)按鈕,導(dǎo)致前端向后端重復(fù)發(fā)送多次請(qǐng)求。這里我列舉兩種比較常見(jiàn)的實(shí)際情況:

  • PC端 - 用戶雙擊搜索按鈕,可能會(huì)觸發(fā)兩次搜索請(qǐng)求
  • 移動(dòng)端 - 因移動(dòng)端沒(méi)有點(diǎn)擊延遲,所以極易造成誤操作或多操作,造成請(qǐng)求重發(fā)

以上情況有可能在有Loading遮罩時(shí)依然發(fā)生,所以我們要考慮前端阻止重復(fù)請(qǐng)求的方法。

核心——CancelToken

在Axios中取消請(qǐng)求最核心的方法是CanelToken。在官網(wǎng)文檔中有寫(xiě)到兩種方法使用CancelToken,這里簡(jiǎn)單粘貼出來(lái),并增加了注釋

方法1:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  // 必須對(duì)請(qǐng)求進(jìn)行cancelToken設(shè)置
  cancelToken: source.token
}).catch(function (thrown) {
  // 如果請(qǐng)求被取消則進(jìn)入該方法判斷
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

// 取消上面的請(qǐng)求
// source.cancel('messge') message為可選項(xiàng),必須為String
source.cancel('Operation canceled by the user.');

方法2:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  // 在options中直接創(chuàng)建一個(gè)cancelToken對(duì)象
  cancelToken: new CancelToken(function executor(c) {
    cancel = c;
  })
});

// 取消上面的請(qǐng)求
cancel();

實(shí)際應(yīng)用和封裝

上文已對(duì)axios中的核心方法進(jìn)行了舉例,但是在實(shí)際中我們往往不會(huì)像官網(wǎng)例子中那樣使用,更多的是在axios的攔截器中做全局配置管理。這樣的話我們需要對(duì)上面的代碼進(jìn)行一些改變。

這里說(shuō)一下我實(shí)現(xiàn)的大體思路:

  • 我們需要對(duì)所有正在進(jìn)行中的請(qǐng)求進(jìn)行緩存。在請(qǐng)求發(fā)起前判斷緩存列表中該請(qǐng)求是否正在進(jìn)行,如果有則取消本次請(qǐng)求。
  • 在任意請(qǐng)求完成后,需要在緩存列表中刪除該次請(qǐng)求,以便可以重新發(fā)送該請(qǐng)求

思路說(shuō)完,我們直接上代碼

// 正在進(jìn)行中的請(qǐng)求列表
let reqList = []

/**
 * 阻止重復(fù)請(qǐng)求
 * @param {array} reqList - 請(qǐng)求緩存列表
 * @param {string} url - 當(dāng)前請(qǐng)求地址
 * @param {function} cancel - 請(qǐng)求中斷函數(shù)
 * @param {string} errorMessage - 請(qǐng)求中斷時(shí)需要顯示的錯(cuò)誤信息
 */
const stopRepeatRequest = function (reqList, url, cancel, errorMessage) {
  const errorMsg = errorMessage || ''
  for (let i = 0; i < reqList.length; i++) {
    if (reqList[i] === url) {
      cancel(errorMsg)
      return
    }
  }
  reqList.push(url)
}

/**
 * 允許某個(gè)請(qǐng)求可以繼續(xù)進(jìn)行
 * @param {array} reqList 全部請(qǐng)求列表
 * @param {string} url 請(qǐng)求地址
 */
const allowRequest = function (reqList, url) {
  for (let i = 0; i < reqList.length; i++) {
    if (reqList[i] === url) {
      reqList.splice(i, 1)
      break
    }
  }
}

const service = axios.create()

// 請(qǐng)求攔截器
service.interceptors.request.use(
  config => {
 let cancel
   // 設(shè)置cancelToken對(duì)象
    config.cancelToken = new axios.CancelToken(function(c) {
     cancel = c
    })
    // 阻止重復(fù)請(qǐng)求。當(dāng)上個(gè)請(qǐng)求未完成時(shí),相同的請(qǐng)求不會(huì)進(jìn)行
    stopRepeatRequest(reqList, config.url, cancel, `${config.url} 請(qǐng)求被中斷`)
    return config
  },
  err => Promise.reject(err)
)

// 響應(yīng)攔截器
service.interceptors.response.use(
  response => {
    // 增加延遲,相同請(qǐng)求不得在短時(shí)間內(nèi)重復(fù)發(fā)送
    setTimeout(() => {
      allowRequest(reqList, response.config.url)
    }, 1000)
    // ...請(qǐng)求成功后的后續(xù)操作
    // successHandler(response)
  },
  error => {
    if (axios.isCancel(thrown)) {
      console.log(thrown.message);
    } else {
      // 增加延遲,相同請(qǐng)求不得在短時(shí)間內(nèi)重復(fù)發(fā)送
      setTimeout(() => {
        allowRequest(reqList, error.config.url)
      }, 1000)
    }
    // ...請(qǐng)求失敗后的后續(xù)操作
    // errorHandler(error)
  }
)

一些小細(xì)節(jié)

為什么沒(méi)用前文方法2中的代碼進(jìn)行cancelToken設(shè)置?
axios的文檔中有一條備注:

Note: you can cancel several requests with the same cancel token.
你可以使用相同的Token來(lái)取消多個(gè)請(qǐng)求

所以我不想在每個(gè)請(qǐng)求前都new一個(gè)新的對(duì)象
請(qǐng)務(wù)必使用方法2,保證每次cancel都能正確執(zhí)行。之前方法會(huì)導(dǎo)致當(dāng)出現(xiàn)cancel后,后續(xù)請(qǐng)求也會(huì)持續(xù)cancel

為什么在response中需要增加延遲?
因?yàn)椴幌胱層脩粼跇O短的時(shí)間內(nèi)重復(fù)進(jìn)行相同請(qǐng)求。
請(qǐng)注意,在response中阻止請(qǐng)求和在request中的阻止請(qǐng)求是兩個(gè)概念:
request中是阻止上個(gè)請(qǐng)求 未完成 時(shí)又開(kāi)始了相同的請(qǐng)求
response中是阻止上個(gè)請(qǐng)求 完成后 一段時(shí)間內(nèi)不允許相同請(qǐng)求

我能否在cancel時(shí)傳遞一個(gè)對(duì)象,而不僅僅是message?
以官方提供的接口來(lái)看是不可以的,你可以仿照官方源碼進(jìn)行重新封裝,或者使用第三方插件,或者使用另一個(gè)方法:將對(duì)象轉(zhuǎn)換為JSON字符串,然后在需要的地方再轉(zhuǎn)換回來(lái)

到此這篇關(guān)于淺談axios中取消請(qǐng)求及阻止重復(fù)請(qǐng)求的方法的文章就介紹到這了,更多相關(guān)axios中取消請(qǐng)求及阻止重復(fù)請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue路由History模式分析

    Vue路由History模式分析

    Vue-router是Vue的核心組件,主要是作為Vue的路由管理器,Vue-router默認(rèn)hash模式,通過(guò)引入Vue-router對(duì)象模塊時(shí)配置mode屬性可以啟用history模式,本文將通過(guò)代碼示例給大家詳細(xì)分析Vue路由History模式
    2023-06-06
  • vue3獲取ref實(shí)例結(jié)合ts的InstanceType問(wèn)題

    vue3獲取ref實(shí)例結(jié)合ts的InstanceType問(wèn)題

    這篇文章主要介紹了vue3獲取ref實(shí)例結(jié)合ts的InstanceType問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • vue深拷貝的3種實(shí)現(xiàn)方式小結(jié)

    vue深拷貝的3種實(shí)現(xiàn)方式小結(jié)

    當(dāng)使用同一個(gè)對(duì)象產(chǎn)生沖突時(shí),可以使用lodash包,對(duì)該對(duì)象進(jìn)行深拷貝,從而使操作的對(duì)象為不同的對(duì)象,這篇文章主要給大家介紹了關(guān)于vue深拷貝的3種實(shí)現(xiàn)方式,需要的朋友可以參考下
    2023-02-02
  • Vuex中的State使用介紹

    Vuex中的State使用介紹

    今天小編就為大家分享一篇關(guān)于Vuex中的State使用介紹,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 解析vue的provide和inject使用方法及其原理

    解析vue的provide和inject使用方法及其原理

    這篇文章主要介紹了vue的provide和inject使用方法及其原理,本文通過(guò)源碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10
  • 詳解本地Vue項(xiàng)目請(qǐng)求本地Node.js服務(wù)器的配置方法

    詳解本地Vue項(xiàng)目請(qǐng)求本地Node.js服務(wù)器的配置方法

    本文只針對(duì)自己需要本地模擬接口于是搭建一個(gè)本地node服務(wù)器供自己測(cè)試使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • 如何在JS文件中獲取Vue組件

    如何在JS文件中獲取Vue組件

    這篇文章主要介紹了如何在JS文件中獲取Vue組件,幫助大家更好的理解和學(xué)習(xí)前端知識(shí),感興趣的朋友可以了解下
    2020-09-09
  • vue在antDesign框架或elementUI框架組件native事件中觸發(fā)2次問(wèn)題

    vue在antDesign框架或elementUI框架組件native事件中觸發(fā)2次問(wèn)題

    這篇文章主要介紹了vue在antDesign框架或elementUI框架組件native事件中觸發(fā)2次問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue中緩存組件keep alive的介紹及使用方法

    vue中緩存組件keep alive的介紹及使用方法

    這篇文章主要介紹了vue緩存組件keepalive的相關(guān)資料,keep-alive組件是使用 include exclude這兩個(gè)屬性傳入組件名稱來(lái)確認(rèn)哪些可以被緩存的,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-08-08
  • Vue攔截器原理以及詳細(xì)使用方法

    Vue攔截器原理以及詳細(xì)使用方法

    這篇文章主要給大家介紹了關(guān)于Vue攔截器原理以及詳細(xì)使用的相關(guān)資料,Vue攔截器通常用于在發(fā)送請(qǐng)求或響應(yīng)數(shù)據(jù)時(shí)對(duì)其進(jìn)行一些處理或修改,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08

最新評(píng)論