成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

后端接口太慢,前端如何優(yōu)雅地實(shí)現(xiàn)一個(gè)“請(qǐng)求隊(duì)列”,避免并發(fā)打爆服務(wù)器?

開(kāi)發(fā)
當(dāng)后端處理不過(guò)來(lái)時(shí),前端一股腦地把請(qǐng)求全發(fā)過(guò)去,只會(huì)讓情況更糟。核心思想就一句話(huà):不要一次性把所有請(qǐng)求都發(fā)出去,讓它們排隊(duì),一個(gè)一個(gè)來(lái),或者一小批一小批來(lái)。

有這樣一些場(chǎng)景:

  • 頁(yè)面一加載,需要同時(shí)發(fā) 10 個(gè)請(qǐng)求,結(jié)果頁(yè)面卡住,服務(wù)器也快崩了。
  • 用戶(hù)可以批量操作,一次點(diǎn)擊觸發(fā)了幾十個(gè)上傳文件的請(qǐng)求,瀏覽器直接轉(zhuǎn)圈圈。

當(dāng)后端處理不過(guò)來(lái)時(shí),前端一股腦地把請(qǐng)求全發(fā)過(guò)去,只會(huì)讓情況更糟。

核心思想就一句話(huà):不要一次性把所有請(qǐng)求都發(fā)出去,讓它們排隊(duì),一個(gè)一個(gè)來(lái),或者一小批一小批來(lái)。

這就好比超市結(jié)賬,只有一個(gè)收銀臺(tái),卻來(lái)了100個(gè)顧客。最好的辦法就是讓他們排隊(duì),而不是一擁而上。我們的“請(qǐng)求隊(duì)列”就是這個(gè)“排隊(duì)管理員”。

直接上代碼:一個(gè)即插即用的請(qǐng)求隊(duì)列

不用復(fù)雜的分析,直接復(fù)制下面的 RequestPool 類(lèi)到我們的項(xiàng)目里。它非常小巧,只有不到 40 行代碼。

/**
 * 一個(gè)簡(jiǎn)單的請(qǐng)求池/請(qǐng)求隊(duì)列,用于控制并發(fā)
 * @example
 * const pool = new RequestPool(3); // 限制并發(fā)數(shù)為 3
 * pool.add(() => myFetch('/api/1'));
 * pool.add(() => myFetch('/api/2'));
 */
class RequestPool {
 /**
   * @param {number} limit - 并發(fā)限制數(shù)
   */
 constructor(limit = 3) {
    this.limit = limit; // 并發(fā)限制數(shù)
    this.queue = [];    // 等待的請(qǐng)求隊(duì)列
    this.running = 0;   // 當(dāng)前正在運(yùn)行的請(qǐng)求數(shù)
  }

 /**
   * 添加一個(gè)請(qǐng)求到池中
   * @param {Function} requestFn - 一個(gè)返回 Promise 的函數(shù)
   * @returns {Promise}
   */
 add(requestFn) {
    return new Promise((resolve, reject) => {
      this.queue.push({ requestFn, resolve, reject });
      this._run(); // 每次添加后,都嘗試運(yùn)行
    });
  }

 _run() {
    // 只有當(dāng) 正在運(yùn)行的請(qǐng)求數(shù) < 限制數(shù) 且 隊(duì)列中有等待的請(qǐng)求時(shí),才執(zhí)行
    while (this.running < this.limit && this.queue.length > 0) {
      const { requestFn, resolve, reject } = this.queue.shift(); // 取出隊(duì)首的任務(wù)
      this.running++;

      requestFn()
        .then(resolve)
        .catch(reject)
        .finally(() => {
          this.running--; // 請(qǐng)求完成,空出一個(gè)位置
          this._run();   // 嘗試運(yùn)行下一個(gè)
        });
    }
  }
}

如何使用?三步搞定!

假設(shè)你有一個(gè)請(qǐng)求函數(shù) mockApi,它會(huì)模擬一個(gè)比較慢的接口。

發(fā)生了什么?

當(dāng)你運(yùn)行上面的代碼,你會(huì)看到:

  • [1] 和 [2] 的請(qǐng)求幾乎同時(shí)開(kāi)始。
  • [3]、[4]、[5]、[6] 在乖乖排隊(duì)。
  • 當(dāng) [1] 或 [2] 中任意一個(gè)完成后,隊(duì)列中的 [3] 馬上就會(huì)開(kāi)始。
  • 整個(gè)過(guò)程,同時(shí)運(yùn)行的請(qǐng)求數(shù)永遠(yuǎn)不會(huì)超過(guò) 2 個(gè)。

控制臺(tái)輸出類(lèi)似這樣:

[1] ?? 請(qǐng)求開(kāi)始...
[2] ?? 請(qǐng)求開(kāi)始...
// (此時(shí) 3, 4, 5, 6 在排隊(duì))

[1] ? 請(qǐng)求完成!
[1] 收到結(jié)果: 任務(wù) 1 的結(jié)果
[3] ?? 請(qǐng)求開(kāi)始...  // 1號(hào)完成,3號(hào)立刻補(bǔ)上

[2] ? 請(qǐng)求完成!
[2] 收到結(jié)果: 任務(wù) 2 的結(jié)果
[4] ?? 請(qǐng)求開(kāi)始...  // 2號(hào)完成,4號(hào)立刻補(bǔ)上

...

它是如何工作的?

(1) add(requestFn): 你扔給它的不是一個(gè)已經(jīng)開(kāi)始的請(qǐng)求,而是一個(gè)“啟動(dòng)器”函數(shù) () => mockApi(i)。它把這個(gè)“啟動(dòng)器”放進(jìn) queue 數(shù)組里排隊(duì)。

(2) _run(): 這是管理員。它會(huì)檢查:

  • 現(xiàn)在有空位嗎?(running < limit)
  • 有人在排隊(duì)嗎?(queue.length > 0)
  • 如果兩個(gè)條件都滿(mǎn)足,就從隊(duì)首叫一個(gè)號(hào)(queue.shift()),讓它開(kāi)始工作(執(zhí)行 requestFn()),并且把正在工作的計(jì)數(shù) running 加一。

(3) .finally(): 這是最關(guān)鍵的一步。每個(gè)請(qǐng)求不管是成功還是失敗,最后都會(huì)執(zhí)行 finally 里的代碼。它會(huì)告訴管理員:“我完事了!”,然后把 running 減一,并再次呼叫管理員 _run() 來(lái)看看能不能讓下一個(gè)人進(jìn)來(lái)。

這樣就形成了一個(gè)完美的自動(dòng)化流程:完成一個(gè),就自動(dòng)啟動(dòng)下一個(gè)。

以后再遇到需要批量發(fā)請(qǐng)求的場(chǎng)景,別再用 Promise.all 一股腦全發(fā)出去了。

把上面那段小小的 RequestPool 代碼復(fù)制到你的項(xiàng)目里,用它來(lái)包裹我們的請(qǐng)求函數(shù)。只需要設(shè)置一個(gè)合理的并發(fā)數(shù)(比如 2 或 3),就能在不修改后端代碼的情況下,大大減輕服務(wù)器的壓力,讓我們的應(yīng)用運(yùn)行得更平穩(wěn)。

這是一種簡(jiǎn)單、優(yōu)雅且非常有效的前端優(yōu)化手段。

責(zé)任編輯:趙寧寧 來(lái)源: JavaScript
相關(guān)推薦

2021-05-12 22:07:43

并發(fā)編排任務(wù)

2020-11-06 08:13:03

服務(wù)器Nodejs客戶(hù)端

2020-02-05 14:05:21

Java技術(shù)數(shù)組

2021-01-04 09:12:31

集合變量

2024-08-05 09:29:00

前端接口請(qǐng)求

2020-12-08 08:08:51

Java接口數(shù)據(jù)

2021-06-17 09:32:39

重復(fù)請(qǐng)求并發(fā)請(qǐng)求Java

2024-06-21 09:19:45

代碼接口重復(fù)請(qǐng)求開(kāi)發(fā)

2022-06-21 14:44:38

接口數(shù)據(jù)脫敏

2024-11-07 10:55:26

2024-11-08 15:56:36

2014-04-14 15:54:00

print()Web服務(wù)器

2019-04-24 15:06:37

Http服務(wù)器協(xié)議

2020-11-03 16:00:33

API接口微服務(wù)框架編程語(yǔ)言

2024-03-15 15:20:10

并發(fā)服務(wù)IP

2025-04-18 10:26:29

后端接口通用封裝

2023-08-01 08:54:02

接口冪等網(wǎng)絡(luò)

2025-02-23 08:00:00

冪等性Java開(kāi)發(fā)

2022-03-02 15:31:32

架構(gòu)網(wǎng)絡(luò)請(qǐng)求代碼

2011-03-17 14:07:39

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 一级特黄a大片 | 一区二区三区四区国产 | 99久久精品视频免费 | 欧美成人激情 | 中文久久 | 亚洲欧洲日本国产 | 日韩一区精品 | 欧美国产一区二区 | 久久久五月天 | 久久99精品久久久久久国产越南 | 午夜精品久久久久久久久久久久久 | 伊人二区 | 91网站在线观看视频 | 亚洲视频在线观看免费 | 欧美一区二区在线看 | 中文字幕在线看第二 | 午夜免费观看体验区 | 亚洲日本欧美 | 国产精品久久久久久久久久久久 | 色综合激情 | 99资源 | 亚洲成人一二区 | 久久久亚洲一区 | 欧美激情va永久在线播放 | 视频一区二区中文字幕 | 免费日韩网站 | 久久国产日韩欧美 | 成人av免费 | 久草视频网站 | 看av在线 | 91精品国产综合久久福利软件 | 成人av看片 | 中文字幕在线网 | 手机在线观看 | 欧美成人视屏 | 一级a性色生活片久久毛片波多野 | 成人在线日韩 | 夜久久 | 亚洲久久一区 | 毛片毛片毛片毛片毛片 | a天堂在线 |