JavaScript實(shí)現(xiàn)指定數(shù)量的并發(fā)限制的示例代碼
在網(wǎng)上看到這么一道題:

這道題跟魚頭這篇記錄『什么是時(shí)間分片(Time Slicing)? 』有點(diǎn)相似,但不同的是這次是限制異步并發(fā)的數(shù)量。
所以話不多說,我們先來康康實(shí)現(xiàn)
首先我們來實(shí)現(xiàn)一個(gè)分割數(shù)組的函數(shù)~
const group = (list = [], max = 0) => {
if (!list.length) {
return list
}
let results = []
for (let i = 0, len = list.length; i < len; i += max) {
results.push(list.slice(i, i + max))
}
return results
}
這里就是根據(jù)指定的并發(fā)數(shù)量來分割數(shù)組。主要就是 for + slice ,這沒啥好說的
接下來我們再來一個(gè)用 async + await 實(shí)現(xiàn)的請求集合封裝。
我們通過 for...of 去遍歷每一個(gè)異步函數(shù),然后用 async + await 確保函數(shù)的執(zhí)行順序,再用 try...catch 來保證即使 reject 報(bào)錯也不會導(dǎo)致無法繼續(xù)執(zhí)行任務(wù)。
const requestHandler = async (
groupedUrl = [],
callback = () => { }
) => {
if (!groupedUrl.length) {
callback()
return groupedUrl
}
const newGroupedUrl = groupedUrl.map(fn => fn())
const resultsMapper = (results) => results.map(callback)
const data = await Promise.allSettled(newGroupedUrl).then(resultsMapper)
return data;
}
接下來就是主函數(shù)
const sendRequest = async (
urls = [],
max = 0,
callback = () => { }
) => {
if (!urls.length) {
return urls
}
const groupedUrls = group(urls, max)
const results = []
console.log('start !')
for (let groupedUrl of groupedUrls) {
try {
const result = await requestHandler(groupedUrl, callback)
results.push(result)
console.log('go')
} catch { }
}
console.log('done !')
return results
}
這里就是利用了 for + async + await 來限制并發(fā)。等每次并發(fā)任務(wù)結(jié)果出來之后再執(zhí)行下一次的任務(wù)。
我們執(zhí)行下栗子:
const p1 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p1'))
const p2 = () => Promise.resolve(2)
const p3 = () => new Promise((resolve, reject) => setTimeout(resolve, 2000, 'p3'))
const p4 = () => Promise.resolve(4)
const p5 = () => new Promise((resolve, reject) => setTimeout(reject, 2000, 'p5'))
const p6 = () => Promise.resolve(6)
const p7 = () => new Promise((resolve, reject) => setTimeout(resolve, 1000, 'p7'))
const p8 = () => Promise.resolve(8)
const p9 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p9'))
const p10 = () => Promise.resolve(10)
const p11 = () => new Promise((resolve, reject) => setTimeout(resolve, 2000, 'p10'))
const p12 = () => Promise.resolve(12)
const p13 = () => new Promise((resolve, reject) => setTimeout(reject, 1000, 'p11'))
const p14 = () => Promise.resolve(14)
const ps = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14]
sendRequest(ps, 3, ({reason, value}) => {
console.log(reason || value)
})

OK,我們看到結(jié)果是如我們所愿的
到此這篇關(guān)于JavaScript實(shí)現(xiàn)指定數(shù)量的并發(fā)限制的示例代碼的文章就介紹到這了,更多相關(guān)JavaScript 指定數(shù)量并發(fā)限制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決bootstrap中modal遇到Esc鍵無法關(guān)閉頁面
Bootstrap,來自 Twitter,是目前最受歡迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它簡潔靈活,使得 Web 開發(fā)更加快捷。不過在使用的過程中,我們還是會遇到各種小問題,今天我們探討的就是個(gè)人在使用中遇到的一個(gè)小BUG的修復(fù)。2015-03-03
JavaScript中檢測數(shù)據(jù)類型的四種方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了四個(gè)JavaScript中檢測數(shù)據(jù)類型的常用方法,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的可以參考一下2023-04-04
javascript+xml實(shí)現(xiàn)簡單圖片輪換(只支持IE)
看著許多網(wǎng)站都有廣告自動輪換;自己試著寫了一個(gè)圖片輪換,代碼和功能都很簡單,只支持IE的,FF的還要加些東東,需要了解的朋友可以參考下2012-12-12
JavaScript函數(shù)中的防抖與節(jié)流原生實(shí)現(xiàn)及第三方庫的使用
當(dāng)你頻繁的觸發(fā)用戶界面時(shí),會不停的觸發(fā)事件處理函數(shù),可能導(dǎo)致界面卡頓,瀏覽器奔潰,頁面空白等情況,而解決這一問題的,正是函數(shù)節(jié)流與函數(shù)防抖,所以本文將給大家介紹一下JavaScript函數(shù)中的防抖與節(jié)流原生實(shí)現(xiàn)及第三方庫的使用,需要的朋友可以參考下2023-10-10
利用JavaScript實(shí)現(xiàn)新聞滾動效果(實(shí)例代碼)
這篇文章主要是對利用JavaScript實(shí)現(xiàn)新聞滾動效果的兩種方法進(jìn)行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助2013-11-11
如何在js代碼中消滅for循環(huán)實(shí)例詳解
for循環(huán)對大家來說都不陌生,下面這篇文章主要給大家介紹了關(guān)于如何在js代碼中消滅for循環(huán)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
JS實(shí)現(xiàn)頁面內(nèi)跳轉(zhuǎn)的簡單代碼
這篇文章主要介紹了JS實(shí)現(xiàn)頁面內(nèi)跳轉(zhuǎn)的簡單代碼,需要的朋友可以參考下2017-09-09
Javascript遞歸打印Document層次關(guān)系實(shí)例分析
這篇文章主要介紹了Javascript遞歸打印Document層次關(guān)系的方法,實(shí)例分析了javascript中Document的層次關(guān)系,需要的朋友可以參考下2015-05-05

