-最近看到了一道面試題,覺(jué)得還蠻有意思,就實(shí)現(xiàn)了一下。面試題如下:
請(qǐng)實(shí)現(xiàn)如下的函數(shù),可以批量請(qǐng)求數(shù)據(jù),所有的URL地址在urls參數(shù)中,
同時(shí)可以通過(guò)max參數(shù) 控制請(qǐng)求的并發(fā)度。當(dāng)所有的請(qǐng)求結(jié)束后,
需要執(zhí)行callback回調(diào)。
發(fā)請(qǐng)求的函數(shù)可以直接使用fetch。
// 請(qǐng)實(shí)現(xiàn)如下的函數(shù),可以批量請(qǐng)求數(shù)據(jù),所有的URL地址在urls參數(shù)中,同時(shí)可以通過(guò)max參數(shù) 控制請(qǐng)求的并發(fā)度。當(dāng)所有的請(qǐng)求結(jié)束后,需要執(zhí)行callback回調(diào)。發(fā)請(qǐng)求的函數(shù)可以直接使用fetch。
const log = console.log.bind()
// 模擬異步url請(qǐng)求
function sleep(i) {
return new Promise((resolve, reject) => {
setTimeout(() => {
log(`我sleep 了${i}毫秒`)
resolve()
}, i)
})
}
// 產(chǎn)生a- b之間的隨機(jī)數(shù)
function random(a, b) {
// floor 一個(gè)表示小于或等于指定的最大整數(shù)的數(shù)字
return a + Math.floor(Math.random() * (b - a))
}
// 異步數(shù)組
function sleepTime(n) {
let arrTime = []
for (let i = 0; i < n; i++) {
let a = random(1200, 20000)
arrTime.push(a)
}
return arrTime
}
let arr = sleepTime(10)
let max = 5
// 處理并發(fā)數(shù)量最大max 數(shù)組中所有數(shù)據(jù)處理完之后 回調(diào) cb
let cb = () => {
log('所有的異步數(shù)據(jù)我都處理完了。。。。。')
}
function handleSleep(arr, max, cb) {
let len = arr.length
let index = 0
let sleepArr = [] // 存放異步請(qǐng)求數(shù)組
function doSleep() {
if (index >= len) {
log('要執(zhí)行全部的sleep了', sleepArr)
Promise.all(sleepArr).then(() => {
cb()
})
} else if (index < len && sleepArr.length < max) {
// 開(kāi)始往sleepArr里面push異步數(shù)據(jù)
let one = sleep(arr[index]).then(() => {
// 這個(gè)處理完了 將其踢出異步隊(duì)列
sleepArr.splice(sleepArr.indexOf(one), 1)
if (sleepArr.length < max && index < len) {
// 如果此時(shí)異步數(shù)組中的長(zhǎng)度 小于最大并發(fā)值
// 并且當(dāng)前index < len (說(shuō)明整個(gè)數(shù)組還沒(méi)有被遍歷完)
// 再次調(diào)用自身
return doSleep()
}
})
log('one', index)
sleepArr.push(one)
// 每次push進(jìn)去之后都會(huì)加1 只有一個(gè)地方更改數(shù)據(jù)比較安全
index++
doSleep()
}
}
doSleep()
}
handleSleep(arr, max, cb)