实现并发请求控制
Published on November 1, 2024
Loading content...
请写一个函数 limitedConcurrentReqs(reqUrls, limit)
实现最大并发数的并发请求。不管请求成功还是失败,都当作结果返回,最后返回一个结果数组,对应每个 reqUrl
的请求结果。
算是 Promise all 的进阶版吧
TypeScriptconst 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()
CODE[ "reject 0", "url: 1 res", "reject 2", "reject 3", "url: 4 res" ] [312.39ms] default