控制请求并发数
需求:有时候你会遇到这么一个需求,比如资源的切片传输,短时间内要连续调用接口,假如该资源需要100个接口调用才能完成传输,但同时调用100个接口,带宽资源也顶不住;又比如你在做某个图表,需要重复调用几十个接口做不同模块的渲染只是入参不同,对服务器不太友好;这时候就需要通过接口并发,限制同一时间请求的接口数量,话不多说直接上码!
- 首先确定入参,我们接受一个请求地址的数组,自动的将该数组里的地址取出进行请求;同时接收一个最大请求的并发数(根据业务和性能自行控制)。
- 出参:我们希望当所有请求完成的时候返回一个结果数组,并且结果数组要对应请求地址的位置,比如请求地址A的位置为0,返回的结果也应存放在结果数组的0位置
🤔思考:如何取出请求数组的地址进行请求呢?
这里我定义了一个指针index,指针根据请求次数自增,当指针超出数组边界停止请求
/**
*
* @param {请求的数组} urls
* @param {请求的并发数} maxNum
* 同时执行maxNum个请求,完成一个就再从urls拿一个继续请求,等所有请求完成之后返回结果数组
*/
export const concurrent = (urls, maxNum) => {
if (!Array.isArray(urls) || !urls?.length) return new Promise.resolve([])
return new Promise((resolve, reject) => {
let index = 0 // 指向下一次请求
let result = [] // 存放请求结果
let count = 0 //请求完成的数量
const _request = async () => {
const i = index
const url = urls[index]
index++
try {
const resp = await request({ url, })
result[i] = resp
} catch (error) {
result[i] = error
} finally {
count++
if (count === urls.length) {
resolve(result) // 所有请求完成
}
if (index < urls?.length) {
_request()
}
}
}
// 最大请求并发数应该取数组真实长度和并发数的最小值
for (let j = 0; j < Math.min(urls.length, maxNum); j++) {
_request()
}
})
}