实现一个带并发数限制的fetch请求函数

459 阅读1分钟
/**
 * 实现一个带并发数限制的fetch请求函数
 * 
 * @param urls url数组
 * @param max  最大并发数
 * @param cb   回调函数
 */
function fetchQueue(urls, max, cb) {
  if (!Array.isArray(urls) || !urls.length) {
    return
  }

  let len = urls.length
  let nexti = 0
  let rc = 0 // runningCount
  let res = []

  function dfsReq(i) {
    // 任务执行完了就不再发起新的请求了
    if (i >= len || rc >= max) {
      return
    }

    nexti = i+1
    rc++
    fetch(urls[i]).then(response => {
      res.push(response)
    }).catch(err => {
      res.push(err)
    }).then(()=>{
      rc--
      if (res.length === len) {
        return cb && cb(res)
      }

      dfsReq(nexti)
    })

    // 如果没有达到并发限制,就尝试发起新的请求【也有可能没有url了,就会在上面停止】
    if (rc < max) {
      dfsReq(nexti)
    }
  }

  dfsReq(nexti)
}