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

前端請(qǐng)求并發(fā)和請(qǐng)求覆蓋的解決方法

 更新時(shí)間:2024年10月25日 08:24:58   作者:Cder  
最近在開發(fā)一些大屏,涉及到比較多的數(shù)據(jù)來(lái)源,接口也沒有做聚合,導(dǎo)致頁(yè)面需要調(diào)很多接口來(lái)填充頁(yè)面數(shù)據(jù),那么就會(huì)有接口并發(fā)的問(wèn)題出現(xiàn),所以本文給大家介紹了如何解決前端請(qǐng)求并發(fā)和請(qǐng)求覆蓋,需要的朋友可以參考下

頁(yè)面太多接口并發(fā)請(qǐng)求會(huì)出現(xiàn)什么問(wèn)題?

  • 服務(wù)器壓力會(huì)變大:大量的并發(fā)請(qǐng)求會(huì)導(dǎo)致服務(wù)器的負(fù)載增加,從而影響服務(wù)器的性能和穩(wěn)定性。
  • 網(wǎng)絡(luò)擁堵:一個(gè)域名最多有 6 個(gè)并發(fā)請(qǐng)求(不同瀏覽器可能限制不一樣),超過(guò) 6 個(gè)并發(fā)請(qǐng)求會(huì)導(dǎo)致網(wǎng)絡(luò)擁堵,從而影響頁(yè)面的加載速度和用戶體驗(yàn)。
  • 響應(yīng)延遲:由于服務(wù)器需要處理大量的并發(fā)請(qǐng)求,所以響應(yīng)延遲會(huì)增加,從而影響頁(yè)面的響應(yīng)速度和用戶體驗(yàn)。

解決方式也有很多,比如:

  • 負(fù)載均衡:分發(fā)請(qǐng)求到多個(gè)服務(wù)器上
  • 聚合接口:將多個(gè)接口合并成一個(gè)接口,減少接口的并發(fā)請(qǐng)求
  • CDN 內(nèi)容分發(fā):通過(guò)不同的域名進(jìn)行請(qǐng)求,從而突破瀏覽器單個(gè)域名并發(fā)請(qǐng)求限制

以上都是基于運(yùn)維和后端的角度,那么前端如何解決呢?

并發(fā)請(qǐng)求

思路:設(shè)置并發(fā)請(qǐng)求限制,用隊(duì)列存放請(qǐng)求,每次請(qǐng)求會(huì)先判斷是否超出設(shè)置的最大并發(fā)請(qǐng)求數(shù),當(dāng)請(qǐng)求完成后,從隊(duì)列中取出下一個(gè)請(qǐng)求,直到隊(duì)列中的請(qǐng)求全部完成。

export class RequestQueue {
  constructor(concurrency = 6) {
    this.concurrency = concurrency; // 設(shè)置最大并發(fā)數(shù),默認(rèn)為6
    this.queue = []; // 存放請(qǐng)求的隊(duì)列
    this.current = 0; // 當(dāng)前正在執(zhí)行的請(qǐng)求數(shù)
  }

  // 處理隊(duì)列中的請(qǐng)求(出隊(duì))
  dequeue() {
    while (this.current < this.concurrency && this.queue.length) {
      this.current++;
      // 從隊(duì)列中取出下一個(gè)請(qǐng)求并執(zhí)行
      const requestPromiseFactory = this.queue.shift();
      requestPromiseFactory()
        .then(() => {
          // 成功的請(qǐng)求邏輯
        })
        .catch((error) => {
          // 失敗
          console.log(error);
        })
        .finally(() => {
          this.current--;
          this.dequeue();
        });
    }
  }

  // 添加請(qǐng)求到隊(duì)列中(入隊(duì))
  enqueue(requestPromiseFactory) {
    this.queue.push(requestPromiseFactory);
    this.dequeue();
  }
}

代碼解釋:

  • 構(gòu)造函數(shù) (constructor):初始化了并發(fā)數(shù) (concurrency)、請(qǐng)求隊(duì)列 (queue) 和當(dāng)前正在執(zhí)行的請(qǐng)求數(shù)量 (current)。
  • 入隊(duì)方法 (enqueue):將請(qǐng)求添加到隊(duì)列中,并立即調(diào)用 dequeue 方法開始處理隊(duì)列。
  • 出隊(duì)方法 (dequeue):從隊(duì)列中取出請(qǐng)求并執(zhí)行。如果請(qǐng)求成功,執(zhí)行成功邏輯;如果請(qǐng)求失敗,捕獲錯(cuò)誤并記錄。無(wú)論成功或失敗,最終都會(huì)調(diào)用 finally 塊來(lái)減少當(dāng)前正在執(zhí)行的請(qǐng)求數(shù)量,并繼續(xù)處理下一個(gè)請(qǐng)求。

實(shí)際使用

const requestQueue = new RequestQueue(6); // 創(chuàng)建一個(gè)并發(fā)數(shù)為6的請(qǐng)求隊(duì)列

// 模擬一個(gè)異步函數(shù)
sleep(fn) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(fn);
    }, 2000);
  });
},

// 生成測(cè)試請(qǐng)求
const queue = [...Array(20)].map((_, i) => () =>
  this.sleep(
    axios
      .get('/api/test' + i)
      .then(r => console.log(i, '成功'))
      .catch(e => console.log('失敗', i))
  )
);

// 添加請(qǐng)求到隊(duì)列中
for (let i = 0; i < queue.length; i++) {
  requestQueue.enqueue(queue[i]);
}

請(qǐng)求覆蓋

場(chǎng)景:先后有A、B兩個(gè)請(qǐng)求,A請(qǐng)求還未返回,B請(qǐng)求已經(jīng)發(fā)起,并且B請(qǐng)求的結(jié)果比A先返回,那么A請(qǐng)求就會(huì)覆蓋B請(qǐng)求的結(jié)果,正常要的結(jié)果是B的結(jié)果覆蓋掉A請(qǐng)求的結(jié)果

可以用隊(duì)列來(lái)維護(hù)請(qǐng)求的順序,按照隊(duì)列的順序發(fā)起請(qǐng)求,但這有種“殺雞用牛刀”的感覺,因?yàn)槲覀兺耆梢匀∠暗恼?qǐng)求,用最新的請(qǐng)求結(jié)果來(lái)賦值

可以通過(guò)以下方式解決請(qǐng)求覆蓋的問(wèn)題:

  • 時(shí)序控制:定全局標(biāo)識(shí),比如數(shù)字,依次累加,每個(gè)請(qǐng)求響應(yīng)中判斷當(dāng)前的標(biāo)識(shí)是否 ≥ 全局標(biāo)識(shí),是則返回結(jié)果,否則不返回結(jié)果。
  • 取消舊請(qǐng)求:發(fā)送新請(qǐng)求時(shí)判斷是否有舊請(qǐng)求,有則取消舊請(qǐng)求,然后再發(fā)送新請(qǐng)求。

方法一:時(shí)序控制

let requestId = 0; // 全局標(biāo)識(shí)

// 發(fā)送請(qǐng)求
function sendRequest() {
  const currentRequestId = ++requestId; // 遞增全局標(biāo)識(shí)

  // 發(fā)起請(qǐng)求
  axios.get('/api/data')
   .then(response => {
      // 判斷當(dāng)前請(qǐng)求是否是最新的請(qǐng)求(如果有新的請(qǐng)求那么requestId在新的請(qǐng)求會(huì)+1,比當(dāng)前這個(gè)方法的curentRequestId的要大)
      if (currentRequestId >= requestId) {
        // 處理響應(yīng)數(shù)據(jù)
        console.log(response.data);
      }
    })
   .catch(error => {
      // 處理錯(cuò)誤
      console.error(error);
    });
}

方法二:取消舊請(qǐng)求

// 通過(guò)axios的cancelToken來(lái)取消請(qǐng)求

let cancelToken; // 取消請(qǐng)求的令牌

// 發(fā)送請(qǐng)求
function sendRequest() {
  // 取消舊請(qǐng)求
  if (cancelToken) {
    cancelToken.cancel();
  }

  // 創(chuàng)建新的取消請(qǐng)求的令牌
  cancelToken = axios.CancelToken.source();

  // 發(fā)起請(qǐng)求
  axios.get('/api/data', {
    cancelToken: cancelToken.token
  })
 .then(response => {
      // 處理響應(yīng)數(shù)據(jù)
      console.log(response.data);
    })
 .catch(error => {
      // 處理錯(cuò)誤
      console.error(error);
    });
}
// 自定義的取消請(qǐng)求函數(shù)
let lastCancel = null;
let cancelable = (req, callback) => {
  let cb = callback;
  req.then(res => {
    cb && cb(res);
  })
  let cancel = () => {
    cb = null;
  }
  return cancel;
}
let sendRequest() {
  lastCancel && lastCancel();
  lastCancel = cancelable(axios.get('/api/data'), res => {
    console.log(res);
  })
}

到此這篇關(guān)于前端請(qǐng)求并發(fā)和請(qǐng)求覆蓋的解決方法的文章就介紹到這了,更多相關(guān)前端請(qǐng)求并發(fā)和請(qǐng)求覆蓋內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于BootStrap Metronic開發(fā)框架經(jīng)驗(yàn)小結(jié)【二】列表分頁(yè)處理和插件JSTree的使用

    基于BootStrap Metronic開發(fā)框架經(jīng)驗(yàn)小結(jié)【二】列表分頁(yè)處理和插件JSTree的使用

    本文給大家介紹基于BootStrap Metronic開發(fā)框架經(jīng)驗(yàn)小結(jié)【二】列表分頁(yè)處理和插件JSTree的使用,介紹頁(yè)面內(nèi)容常用到的數(shù)據(jù)分頁(yè)處理,以及Bootstrap插件JSTree的使用,非常具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • 微信小程序?qū)崿F(xiàn)上拉加載功能

    微信小程序?qū)崿F(xiàn)上拉加載功能

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)上拉加載功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • javascript實(shí)現(xiàn)獲取服務(wù)器時(shí)間

    javascript實(shí)現(xiàn)獲取服務(wù)器時(shí)間

    本文給大家總結(jié)了一下使用javascript來(lái)獲取服務(wù)器時(shí)間的幾種方法和思路,十分的簡(jiǎn)單明了,有需要的小伙伴可以參考下
    2015-05-05
  • ES6中l(wèi)et、const的區(qū)別及變量的解構(gòu)賦值操作方法實(shí)例分析

    ES6中l(wèi)et、const的區(qū)別及變量的解構(gòu)賦值操作方法實(shí)例分析

    這篇文章主要介紹了ES6中l(wèi)et、const的區(qū)別及變量的解構(gòu)賦值操作方法,結(jié)合實(shí)例形式分析了ES6中l(wèi)et、const的功能、原理、使用方法及數(shù)組、字符串、函數(shù)參數(shù)等解構(gòu)賦值相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10
  • js數(shù)據(jù)類型以及其判斷方法實(shí)例

    js數(shù)據(jù)類型以及其判斷方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于js數(shù)據(jù)類型以及其判斷方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • webpack配置的最佳實(shí)踐分享

    webpack配置的最佳實(shí)踐分享

    在網(wǎng)上看到很多人都寫了“webpack最佳實(shí)踐方案”,適合的才是“最佳”的,在這里總結(jié)一下自己在工作過(guò)程中總結(jié)出來(lái)的最佳實(shí)踐,所以本文主要介紹了關(guān)于webpack配置的相關(guān)資料,需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2017-04-04
  • 利用PHP實(shí)現(xiàn)遞歸刪除鏈表元素的方法示例

    利用PHP實(shí)現(xiàn)遞歸刪除鏈表元素的方法示例

    這篇文章主要給大家介紹了關(guān)于如何利用PHP實(shí)現(xiàn)遞歸刪除鏈表元素的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 微前端qiankun沙箱實(shí)現(xiàn)源碼解讀

    微前端qiankun沙箱實(shí)現(xiàn)源碼解讀

    這篇文章主要為大家介紹了微前端qiankun沙箱實(shí)現(xiàn)的源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 詳解微信小程序之scroll-view的flex布局問(wèn)題

    詳解微信小程序之scroll-view的flex布局問(wèn)題

    這篇文章主要介紹了詳解微信小程序之scroll-view的flex布局問(wèn)題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • url特殊字符編碼encodeURI?VS?encodeURIComponent分析

    url特殊字符編碼encodeURI?VS?encodeURIComponent分析

    這篇文章主要介紹了url特殊字符編碼encodeURI?VS?encodeURIComponent分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09

最新評(píng)論