控制并发下载量?简易版

141 阅读1分钟

有这么一个需求,那就是批量下载,控制并发请求?

前端: 这不容易吗,让后端干,将下载的内容一次性打包成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
              })
            }
          })
      }
    }
  }
}