JavaScript實現(xiàn)控制并發(fā)請求數(shù)量的方法詳解
前言
嗨呀,又是將近一個月沒有更文了,想死你們了!今天又來繼續(xù)我的更文事業(yè),技術的道路注定是要將卷進行到底的!至于這么久才來更文的原因,那自然是沒有好的羊毛值得去薅,一旦有好羊毛那當然是也不會缺席的,所以今天我來了!
這次要分享的主題就是前久飯后在和同事討論時無意間發(fā)現(xiàn)的,那就是前端如何實現(xiàn)并發(fā)請求數(shù)量控制。如果你在實際項目中有過類似的需求,應該不會陌生,反之如果你還沒有且還不了解的話,那你就有必要耐心地看完這篇文章,保證你一定會有所收獲的!
場景
假設有這么一個場景:現(xiàn)在有20個異步請求需要發(fā)送,但是由于某些原因,要求我們必須將同一時刻的并發(fā)請求數(shù)量控制在3個以內,并且還要盡可能快速的拿到響應結果。其實這個場景在一些大廠的面試題中也有過提及,如下:
實現(xiàn)一個并發(fā)請求函數(shù)concurrencyRequest(urls, maxNum),要求如下:
• 要求最大并發(fā)數(shù) maxNum
• 每當有一個請求返回,就留下一個空位,可以增加新的請求
• 所有請求完成后,結果按照 urls 里面的順序依次打出(發(fā)送請求的函數(shù)可以直接使用fetch即可)
遇到到這個問題時你會怎么來做?
遇到這個問題還是先來分析一下這個問題的設計思路→。
設計思路
首先來看將上面的文字轉化為圖之后的效果:

這樣就直觀的看到,有一個最大并發(fā)數(shù)maxNum,20個異步請求的urls集合和并發(fā)返回之后的results集合。
下面就開始演示這個思路是如何開始的,如下:

首先按照每次只能并發(fā)3個請求的要求,這里就對應A、B、C,當其中有一個請求完之后就會再從urls里面再取出一個進行請求,這樣依次類推,直到urls里面的20個請求都執(zhí)行完才終止請求。

主要思路就是上面所述,但是在開發(fā)時我們要考慮一些特殊情況,如下:
urls的長度為0時,results就沒有值,此時應該返回空數(shù)組maxNum大于urls的長度時,應該取的是urls的長度,否則則是取maxNum- 需要定義一個
count計數(shù)器來判斷是否已全部請求完成 - 因為沒有考慮請求是否請求成功,所以請求成功或報錯都應把結果保存在
results集合中 results中的順序需和urls中的保持一致
好,我的設計思路就是這樣的,下面就要來開始開發(fā)工作啦~
開發(fā)
具體代碼如下(代碼中已備注有注釋):
// 并發(fā)請求函數(shù)
const concurrencyRequest = (urls, maxNum) => {
return new Promise((resolve) => {
if (urls.length === 0) {
resolve([]);
return;
}
const results = [];
let index = 0; // 下一個請求的下標
let count = 0; // 當前請求完成的數(shù)量
// 發(fā)送請求
async function request() {
if (index === urls.length) return;
const i = index; // 保存序號,使result和urls相對應
const url = urls[index];
index++;
console.log(url);
try {
const resp = await fetch(url);
// resp 加入到results
results[i] = resp;
} catch (err) {
// err 加入到results
results[i] = err;
} finally {
count++;
// 判斷是否所有的請求都已完成
if (count === urls.length) {
console.log('完成了');
resolve(results);
}
request();
}
}
// maxNum和urls.length取最小進行調用
const times = Math.min(maxNum, urls.length);
for(let i = 0; i < times; i++) {
request();
}
})
}
測試
測試代碼如下:
const urls = [];
for (let i = 1; i <= 20; i++) {
urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
}
concurrencyRequest(urls, 3).then(res => {
console.log(res);
})
結果
下面通過運行代碼來看看效果:
首先來看看控制臺輸出的結果,如下:


可以看到20個請求都請求完成,results里面也是按順序打印出了結果。
然后再看看請求時請求數(shù)量是否每次都是3個,如下:

通過上面這個gif圖可以很直觀的看到,每次請求的數(shù)量都是3個,證明寫的代碼沒有毛病,搞定!
至此,這個在實際開發(fā)中會遇見的前端控制并發(fā)請求的需求就實現(xiàn)完成了。代碼相對來說沒有太大的難度,只要把一些特殊情況給考慮完全,最后的實現(xiàn)也就沒什么太大問題。最后,希望看完這篇文章之后你也能輕松掌握前端控制并發(fā)數(shù)量的問題,栓Q~
以上就是JavaScript實現(xiàn)控制并發(fā)請求數(shù)量的方法詳解的詳細內容,更多關于JavaScript控制并發(fā)請求數(shù)量的資料請關注腳本之家其它相關文章!
相關文章
微信小程序中data-key屬性之數(shù)據傳輸(經驗總結)
這篇文章主要介紹了微信小程序中data-key屬性:數(shù)據傳輸,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
JavaScript知識點總結(五)之Javascript中兩個等于號(==)和三個等于號(===)的區(qū)別
這篇文章主要介紹了JavaScript知識點總結(五)之Javascript中兩個等于號(==)和三個等于號(===)的區(qū)別的相關資料,需要的朋友可以參考下2016-05-05

