前言
假设现在有这么一种场景:现有30个异步请求需要发送,但由于浏览器每次发出请求都会建立TCP连接,不同的浏览器有TCP连接限制,谷歌是建立超过6个之后就会卡顿,所以我们必须将同一时刻并发请求数量控制在6个以内,同时还要尽可能快速的拿到响应结果。
应该怎么做?接下来继续往下看。
实现
- 准备数据,用于模式并发数量,下面的相当于同时发出15个请求。
const chunk = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
- 模拟请求,通过setTimeout结合随机数控制,模拟不同的请求返回时间。
function sendRequest(task) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(task) }, Math.random() * 2000) }) }
- 并发控制并统计累计错误次数,报错3次直接中断请求。
let errorCount = 0 // 累计报错次数 // 并发控制, 错误重试 function concurrent(chunks = [], limit) { return new Promise((resolve, reject) => { let len = chunks.length // 记录总任务数 let count = 0 // 用于记录任务是否执行完成 // 启动任务 const start = async () => { const task = chunks.shift() // 拿出一个任务 // 如果有任务执行 if (task) { try { const ret = await sendRequest(task) console.log(ret); if (count === len - 1) { resolve() } else { count++ start() } } catch (error) { // 如果错误请求没超过3次,重新进行请求,超过3次之后退出请求状态 if (errorCount < 3) { start() } else { console.log('退出请求', error) reject() } } } } // 控制最多发送的次数 while (limit > 0) { start() limit -= 1 } }) }
结语
这样我们就实现了异步并发任务控制,并且还完成了错误之后的重试。这道题目呢我想很多同学都或多或少的见过,这其实就是字节的一道面试题。
实现一个批量请求函数 multiRequest(urls, maxNum),要求如下: • 要求最大并发数 maxNum • 每当有一个请求返回,就留下一个空位,可以增加新的请求 • 所有请求完成后,结果按照 urls 里面的顺序依次打出希望我的文章可以帮助xdm,更好的完成异步并发控制的功能。如果文章对你有帮助请帮忙给熊猫小弟点赞 ,关注 + 评论。
熊猫小弟会持续进行技术文章的输出,xdm的点赞就是我坚持下去的动力,感谢大家🙏🙏🙏。