Last updated on
实现并发请求控制
Q
请写一个函数 limitedConcurrentReqs(reqUrls, limit) 实现最大并发数的并发请求。不管请求成功还是失败,都当作结果返回,最后返回一个结果数组,对应每个 reqUrl 的请求结果。
A
算是 Promise all 的进阶版吧
const randomRequest = (url, success) => {
return new Promise<string>((resolve, reject) => {
setTimeout(() => {
success ? resolve(`url: ${url} res`) : reject(`reject ${url}`)
}, 100);
})
}
const limitedConcurrentReqs = async (reqUrls: string[], limit: number) => {
if (limit <= 0) {
throw new Error(`Invalid limit: ${limit}`)
}
return new Promise((resolve) => {
const results: string[] = []
let nextIndex = 0
let completedCount = 0
const processRequest = async () => {
const currentIndex = nextIndex
nextIndex += 1
if (currentIndex >= reqUrls.length) return
try {
const result = await randomRequest(reqUrls[currentIndex], Math.random() > 0.5)
results[currentIndex] = result
} catch (error) {
results[currentIndex] = error
}
completedCount += 1
if (completedCount === reqUrls.length) {
resolve(results)
return
}
// Process next request if any remaining
processRequest()
}
// Initialize concurrent requests up to the limit
const initialCount = Math.min(limit, reqUrls.length)
for (let i = 0; i < initialCount; i++) {
processRequest()
}
})
}
console.time()
console.log(await limitedConcurrentReqs(Array.from({ length: 5 }).map((_, index) => `${index}`), 2))
console.timeEnd()
[ "reject 0", "url: 1 res", "reject 2", "reject 3", "url: 4 res" ]
[312.39ms] default