Promise并发限制

40 阅读1分钟
/**
 * Promise并发限制
 * @param urls:string【】 - 请求地址列表
 * @param limit:number - 并发限制数量
 * @returns result:Promise<any>[] - 请求结果列表
 */

export function requestLimit (urls: string[], limit: number) {
  return new Promise<any[]>((resolve) => {
    if (urls.length === 0) {
      resolve([])
      return
    }

    const results: any[] = []
    let index = 0 // 移动的索引值
    let indx = 0 // 当前的索引值
    let count = 0 // 请求次数
    async function request () {
      const url = urls[index]
      indx = index
      index++
      try {
        const resp = await fetch(url)
        results[indx] = resp
      }
      catch (err) {
        results[indx] = err
      }
      finally {
        count++
        if (count === urls.length)
          resolve(results)
        request()
      }
    }

    const times = Math.min(urls.length, limit)
    for (let i = 0; i < times; i++) {
      request()
    }
  })
}