有这么一个需求,那就是批量下载,控制并发请求?
前端: 这不容易吗,让后端干,将下载的内容一次性打包成zip压缩包一次返回给前端,别烦死人。
后端: 不干,这显得我接口很慢,相当于后端也是拿到oss链接一个个下载打包压缩包才返回给你们,还不如你们自己去控制,你们下载不用走一遍后台,能直接通过oss下载查看下载进度。
前端: ……哦
有个基础知识,浏览器http1.0 / http1.1同个域名下并发请求为6个。
行吧,写个简略版控制并发请求的公共方法,有不对的地方欢迎讨论下,或者有更好的方法优化下。
/**
*
* @param api 请求的api
* @param ids 请求的ids,这个根据需求自定义参数吧
* @param batchCount 同时进行下载的数量
* @returns Promise 返回失败和成功的ids数组
*/
export async function downloadBatch(
api: (id: string) => Promise<any>,
ids: string[],
batchCount = 6
) {
let downloadingCount: number = batchCount // 下载并发数量
const successIds: string[] = [] // 成功的id数组
const errorIds: string[] = [] // 失败的id数组
const idArr: string[] = ids // 总的idArr
const res = await limitDownload()
return res
async function limitDownload() {
while (downloadingCount > 0 && idArr.length) {
downloadingCount -= 1
const id = idArr.pop()
if (id) {
api(id)
.then((url) => {
download(url, url.split('/').pop() as string)
successIds.push(id)
})
.catch(() => {
errorIds.push(id)
})
.finally(() => {
downloadingCount += 1
console.log(idArr.length, downloadingCount)
if (idArr.length) {
limitDownload()
} else if (!idArr.length && downloadingCount === batchCount) {
Promise.resolve({
successIds,
errorIds
})
}
})
}
}
}
}