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

web開發(fā)中如何優(yōu)雅的解決"重復(fù)請(qǐng)求"問題

 更新時(shí)間:2022年05月06日 12:07:10   作者:舒麗琦|奇舞團(tuán)前端開發(fā)工程師  
在我們的日常開發(fā)當(dāng)中,很多時(shí)候會(huì)出現(xiàn)短時(shí)間內(nèi)重復(fù)請(qǐng)求的情況,如果沒有妥當(dāng)?shù)靥幚砗蠊車?yán)重,這篇文章主要給大家介紹了關(guān)于web開發(fā)中如何優(yōu)雅的解決重復(fù)請(qǐng)求問題的相關(guān)資料,需要的朋友可以參考下

前言

在我們web開發(fā)過程中,很多地方需要我們?nèi)∠貜?fù)的請(qǐng)求。但是哪種場(chǎng)合需要我們?nèi)∠兀课覀內(nèi)绾稳∠??帶著這些問題我們閱讀本文。

閱讀完本文,你將了解以下內(nèi)容:

需要取消重復(fù)請(qǐng)求的場(chǎng)景

我們?nèi)绾稳∠貜?fù)請(qǐng)求

axios如何取消重復(fù)的請(qǐng)求

封裝axios

如何給開源的項(xiàng)目提供源碼

如何在本地調(diào)試npm包

提出問題

最近做的項(xiàng)目中,用的用戶經(jīng)常遇到這樣的問題:

  • 用戶頻繁切換篩選條件去請(qǐng)求數(shù)據(jù),初次的篩選條件數(shù)據(jù)量大。用的時(shí)間比較多。后面的篩選條件的數(shù)據(jù)量小。導(dǎo)致后面請(qǐng)求的數(shù)據(jù)先返回。內(nèi)容先顯示在頁面上。但是等一段時(shí)間,初次(或者前面)的請(qǐng)求數(shù)據(jù)返回了, 會(huì)覆蓋后面的請(qǐng)求的數(shù)據(jù)。這就導(dǎo)致了篩選條件和內(nèi)容不一致的情況。
  • 用戶點(diǎn)擊了一次提交按鈕,接口沒有很快響應(yīng),導(dǎo)致頁面沒辦法做邏輯語句判斷的提示。用戶覺得可能沒提交上,便會(huì)快速又點(diǎn)了按鈕幾次。如果后端沒有去重的判斷,就會(huì)導(dǎo)致數(shù)據(jù)中有很多條重復(fù)的數(shù)據(jù)。

這些問題給用戶的體驗(yàn)是很不友好的。那么取消無用的請(qǐng)求是很有必要的。

解決思路

我們用的請(qǐng)求庫是axios。那么我們可以在請(qǐng)求的時(shí)候攔截請(qǐng)求判斷當(dāng)前的請(qǐng)求是否重復(fù),如果重復(fù)我們就取消當(dāng)前的請(qǐng)求。大致的實(shí)現(xiàn)過程如下:

我們把目前處于pending的請(qǐng)求存儲(chǔ)(假如我們放在一個(gè)數(shù)組)起來。每個(gè)請(qǐng)求發(fā)送之前我們都要判斷當(dāng)前這個(gè)請(qǐng)求是否已經(jīng)存在于這個(gè)數(shù)組。如果存在,說明請(qǐng)求重復(fù)了,我們就在數(shù)組中找到重復(fù)的請(qǐng)求并且取消。如果不存在,說明這個(gè)請(qǐng)求不是重復(fù)的,正常發(fā)送并且把這個(gè)請(qǐng)求api添加在數(shù)據(jù)中,等請(qǐng)求結(jié)束之后刪除數(shù)組中的這個(gè)api。

我們這個(gè)解決思路有了,但是axios如何取消請(qǐng)求的呢?我們先來了解下

axios 如何取消請(qǐng)求

查看axios文檔發(fā)現(xiàn)axios提供了兩種取消請(qǐng)求的方法(http://www.axios-js.com/zh-cn/docs/#%E5%8F%96%E6%B6%88)

第一種方法

通過axios.CancelToken.source生成取消令牌token和取消方法cancel

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 處理錯(cuò)誤
  }
});
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})
// 取消請(qǐng)求 (消息參數(shù)是可選的)
source.cancel('Operation canceled by the user.');

第二種方式

通過傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建 cancel token

const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函數(shù)接收一個(gè) cancel 函數(shù)作為參數(shù)
    cancel = c;
  })
});
// 取消請(qǐng)求
cancel();

封裝axios

解決取消請(qǐng)求的思路有了,取消請(qǐng)求的辦法也有了,那么剩下的就是封裝了

由于同事之前已經(jīng)封裝了axios——very-axios(https://github.com/verymuch/very-axios) (基于 axios 進(jìn)行二次封裝,更簡(jiǎn)單、更統(tǒng)一地使用 axios)。那么我們就這個(gè)基礎(chǔ)上提一個(gè)pr吧。那么從現(xiàn)在開始我們就一步一步的來實(shí)現(xiàn),這個(gè)過程包含了【如何給開源的項(xiàng)目貢獻(xiàn)代碼】【如何在本地調(diào)試npm】如果已經(jīng)了解的同學(xué)可以直接略過。

準(zhǔn)備工作

由于同事已經(jīng)封裝了axios并且已經(jīng)開源了。那么我貢獻(xiàn)代碼的方式主要有兩種:

  • 代碼倉庫的管理者給我們添加這個(gè)倉庫的寫入權(quán)限,如果這樣,我們就可以直接提push。
  • 如果我們沒有權(quán)限(大多數(shù)情況)。我們使用經(jīng)典的fork & pull request 的方式來提交代碼。

我們采用的第二種方式。我們?nèi)?very-axios(https://github.com/verymuch/very-axios) 把代碼fork到自己的倉庫(如果你還沒有自己的github,需要自己注冊(cè)下哦)。

那么你回到自己的github倉庫下面就會(huì)看有一個(gè)一摸一樣的項(xiàng)目

那么我們現(xiàn)在就可以git clone這個(gè)倉庫的代碼到本地,新建branch進(jìn)行開發(fā),就比如我新建了一個(gè)這樣的branch:

現(xiàn)在已經(jīng)有本地的代碼了,但是我們?nèi)绾伪镜鼗{(diào)試npm包呢?那就需要npm link 了

首先在我們要修改的npm 包中npm link:

之后我們會(huì)得到

/Users/shuliqi/.nvm/versions/node/v12.17.0/lib/node_modules/very-axios -> /Users/shuliqi/study/axios/very-axios

這意思就是我們把very-axios鏈接到全局的node_modules

然后我們進(jìn)入我們my-project-of-axios 目錄下面執(zhí)行npm link very-axios 如圖:

這意思就是very-axios被安裝在my-project-of-axios 下面了。very-axios的修改都會(huì)同步到my-project-of-axios。就實(shí)現(xiàn)本地測(cè)試了。

我們?cè)趍y-project-of-axios中的HelloWorld.vue文件中做列子。

如果這里看的不是很懂的同學(xué)可以看看這兩篇文章:如何在本地調(diào)試npm包(https://github.com/allenGKC/Blog/issues/13)。如何使用 GitHub Flow 給開源項(xiàng)目貢獻(xiàn)代碼(https://juejin.im/post/6844903636863041550)

開始封裝

準(zhǔn)備工作完成了, 那我們開始封裝的事情。根據(jù)我們之前的思路。我們采用axios 如何取消請(qǐng)求的第一種方式。

聲明一個(gè)Map。用來存儲(chǔ)每個(gè)請(qǐng)求的 標(biāo)識(shí) 和 取消的函數(shù)

// 存儲(chǔ)每個(gè)請(qǐng)求的標(biāo)識(shí)和取消的函數(shù)
this.pendingAjax = new Map();

自定一個(gè)字段來讓用戶自己決定是否需要取消重復(fù)的請(qǐng)求

// 是否取消重復(fù)的請(qǐng)求
cancelDuplicated = false,

自定一個(gè)字段來讓用戶是否有全局的統(tǒng)一的設(shè)置重復(fù)標(biāo)識(shí)的函數(shù)。如果沒有設(shè)置全局的統(tǒng)一的函數(shù),則默認(rèn)是請(qǐng)求的method 和url作為重復(fù)的標(biāo)識(shí)

// 生成重復(fù)標(biāo)識(shí)的方式
duplicatedKeyFn,
this.duplicatedKeyFn = isFunction(duplicatedKeyFn) ? duplicatedKeyFn : (config) => `${config.method}${config.url}`;

添加請(qǐng)求

/**
 * 將請(qǐng)求添加到pendingAjax
 * @param {Object} config
 */
addPendingAjax(config) {
  // 是否需要取消重復(fù)的請(qǐng)求
  if (!this.cancelDuplicated) return
  const veryConfig = config.veryConfig || {};
  const duplicatedKey = JSON.stringify({
    duplicatedKey: veryConfig.duplicatedKey || this.duplicatedKeyFn(config),
    type: REQUEST_TYPE.DUPLICATED_REQUEST,
  });
  config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
    // 如果pendingAjax中不存在當(dāng)前請(qǐng)求,添加進(jìn)去
    if (duplicatedKey && !this.pendingAjax.has(duplicatedKey)) {
      this.pendingAjax.set(duplicatedKey, cancel);
    }
  });
}

這里面我們可以使用duplicatedKey字段來讓用戶對(duì)單一請(qǐng)求自定義重復(fù)的標(biāo)識(shí)?;蛘呖梢允褂靡粋€(gè)函數(shù)duplicatedKeyFn統(tǒng)一的讓用戶自定義重復(fù)的標(biāo)識(shí)

刪除請(qǐng)求

/**
   * 從pendingAjax中刪除請(qǐng)求
   * @param {Object} config
   */
  removePendingAjax(config) {
    // 是否需要取消重復(fù)的請(qǐng)求
    if (!this.cancelDuplicated) return
    const veryConfig = config.veryConfig || {};
    const duplicatedKey = JSON.stringify({
      duplicatedKey: veryConfig.duplicatedKey || this.duplicatedKeyFn(config),
      type: REQUEST_TYPE.DUPLICATED_REQUEST,
    });
    // 如果pendingAjax中存在當(dāng)前請(qǐng)求, 取消當(dāng)前請(qǐng)求并將其刪除
    if (duplicatedKey && this.pendingAjax.has(duplicatedKey)) {
      const cancel = this.pendingAjax.get(duplicatedKey);
      cancel(duplicatedKey);
      this.pendingAjax.delete(duplicatedKey);
    }
  }

封裝好了, 我們?cè)谀睦锸褂媚??肯定是在?qǐng)求開始之前和請(qǐng)求完成之后使用。

在請(qǐng)求之前

// 攔截請(qǐng)求
this.axios.interceptors.request.use((config) => {
  // 在請(qǐng)求開始之前檢查先前的請(qǐng)求
  this.removePendingAjax(config);
  // 將當(dāng)前請(qǐng)求添加到pendingAjax
  this.addPendingAjax(config);
  // ...
});

在請(qǐng)求完成之后去掉該請(qǐng)求

// 攔截響應(yīng)
this.axios.interceptors.response.use(response => {
  removePending(response)
  return response
}, error => {
  // ...
})

到現(xiàn)在已經(jīng)完成了該有的功能, 但是取消請(qǐng)求的錯(cuò)誤我們不該返回給用戶。所以:

(err) => {
// 類型是否為重復(fù)請(qǐng)求
let isDuplicatedType;
try {
  const errorType = (JSON.parse(error.message) || {}).type
  isDuplicatedType = errorType === REQUEST_TYPE.DUPLICATED_REQUEST;
} catch (error) {
  isDuplicatedType = false
}
if (isDuplicatedType) return;
}

我們?cè)谡?qǐng)求完成之后的err里面做一個(gè)判斷,判斷如果當(dāng)前請(qǐng)求是取消的類型,我們就不返回給用戶錯(cuò)誤的提示信息。

總結(jié)

至此,完成了我們的封裝。完成的pr地址:(https://github.com/verymuch/very-axios/pull/1)。本文測(cè)試npm包的項(xiàng)目地址:(https://github.com/shuliqi/my-project-of-axios)

到此這篇關(guān)于web開發(fā)中如何優(yōu)雅的解決"重復(fù)請(qǐng)求"問題的文章就介紹到這了,更多相關(guān)axios取消重復(fù)請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vuejs移動(dòng)端實(shí)現(xiàn)div拖拽移動(dòng)

    vuejs移動(dòng)端實(shí)現(xiàn)div拖拽移動(dòng)

    這篇文章主要為大家詳細(xì)介紹了vuejs移動(dòng)端實(shí)現(xiàn)div拖拽移動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • vue打印功能實(shí)現(xiàn)的兩種方法總結(jié)

    vue打印功能實(shí)現(xiàn)的兩種方法總結(jié)

    在項(xiàng)目中,有時(shí)需要打印頁面的表格,所以下面這篇文章主要給大家介紹了關(guān)于vue打印功能實(shí)現(xiàn)的兩種方法,以及批量打印的完整代碼,需要的朋友可以參考下
    2021-06-06
  • vue組件間通信解析

    vue組件間通信解析

    這篇文章主要為大家詳細(xì)介紹了vue組件間通信解析,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • vue單頁面應(yīng)用部署配置詳解

    vue單頁面應(yīng)用部署配置詳解

    本文主要介紹了vue單頁面應(yīng)用部署配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • vue 檢測(cè)用戶上傳圖片寬高的方法

    vue 檢測(cè)用戶上傳圖片寬高的方法

    這篇文章主要介紹了vue 檢測(cè)用戶上傳圖片寬高的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • vue項(xiàng)目中使用TDesign的方法

    vue項(xiàng)目中使用TDesign的方法

    tdesign-vue是TDesign 適配桌面端的組件庫,適合在 vue 2 技術(shù)棧項(xiàng)目中使用,這篇文章主要介紹了vue項(xiàng)目中使用TDesign?,需要的朋友可以參考下
    2023-04-04
  • Vue中的Strorage本地化存儲(chǔ)詳解

    Vue中的Strorage本地化存儲(chǔ)詳解

    這篇文章主要介紹了Vue中的Strorage本地化存儲(chǔ)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • element-ui配合node實(shí)現(xiàn)自定義上傳文件方式

    element-ui配合node實(shí)現(xiàn)自定義上傳文件方式

    這篇文章主要介紹了element-ui配合node實(shí)現(xiàn)自定義上傳文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue動(dòng)態(tài)生成表格的行和列

    Vue動(dòng)態(tài)生成表格的行和列

    這篇文章主要為大家詳細(xì)介紹了Vue動(dòng)態(tài)生成表格的行和列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Vue3+Vite實(shí)現(xiàn)動(dòng)態(tài)路由的詳細(xì)實(shí)例代碼

    Vue3+Vite實(shí)現(xiàn)動(dòng)態(tài)路由的詳細(xì)實(shí)例代碼

    我們?cè)陂_發(fā)大型系統(tǒng)的時(shí)候一般都需要?jiǎng)討B(tài)添加路由,下面這篇文章主要給大家介紹了關(guān)于Vue3+Vite實(shí)現(xiàn)動(dòng)態(tài)路由的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08

最新評(píng)論