如何实现并发请求控制(限制同时发起的请求数量)?

方案:维护一个执行队列

async function concurrentLimit(tasks, limit) {
  const results = []
  const executing = new Set()

  for (const task of tasks) {
    // 创建 Promise 并加入执行集合
    const p = task().then(result => {
      executing.delete(p)
      return result
    })
    executing.add(p)
    results.push(p)

    // 当并发数达到上限,等待最快的一个完成
    if (executing.size >= limit) {
      await Promise.race(executing)
    }
  }

  return Promise.all(results)
}

使用示例

// 模拟 10 个请求,限制并发 3
const urls = Array.from({ length: 10 }, (_, i) => `/api/${i}`)
const tasks = urls.map(url => () =>
  fetch(url).then(r => r.json())
)

concurrentLimit(tasks, 3).then(results => {
  console.log('全部完成:', results)
})

进阶版:支持回调通知

class ConcurrentPool {
  constructor(limit) {
    this.limit = limit
    this.queue = []
    this.active = 0
  }

  add(task) {
    return new Promise((resolve, reject) => {
      this.queue.push({ task, resolve, reject })
      this.run()
    })
  }

  run() {
    while (this.active < this.limit && this.queue.length) {
      const { task, resolve, reject } = this.queue.shift()
      this.active++
      task()
        .then(resolve)
        .catch(reject)
        .finally(() => {
          this.active--
          this.run()
        })
    }
  }
}

// 使用
const pool = new ConcurrentPool(3)
urls.forEach(url => pool.add(() => fetch(url)))

实际应用场景

同分类其他题目