js控制并发请求

一. 设计思路

功能:目的在有限的并发池中运行多个 promise 返回和异步函数。

  1. 添加异步任务
  2. 执行异步任务
  3. 限制最大并发数量

二.实现


interface Fn {
  (): Promise<any>
}
export default class Pipeline {
  private list: { // 请求队列
    fn: Fn,
    resolve: (value: any) => void
    reject: (err: any) => void
  }[]
  private count = 0 // 当前并发数量
  private max = 0 // 最大并发数量

  constructor (max: number) {
    this.max = max
    this.count = 0
    this.list = []
  }

  // 添加请求任务
  add (fn:Fn) {
    return new Promise((resolve, reject) => {
      this.list.push({
        fn,
        resolve,
        reject
      })
      this.run()
    })
  }
  // 执行任务
  run () {
    // 如果当前并发数小于最大并发数量
    if(this.count < this.max && this.list.length ) {
      const { fn, resolve, reject } = this.list.shift()!
      if(fn) {
        // 每执行一个,当前并发+1
        this.count++
        fn().then((res) => {
          resolve(res)
        }).catch(err => {
          reject(err)
        }).finally (() => {
          // 每完成一个请求
          this.count--
          this.run()
        }) 
      }
    }
  }
}

三. 使用

import Pipeline from "./pipeline"
interface Fn {
  () : Promise<any>
}
// 创建50个请求
function createRequest () {
  const arr: Fn[] = []
  for(let i=0; i < 50; i++) {
    arr.push(() => new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(i)
      }, 2 * 2000)
    })) 
  }
  return arr
}

export async function request() {
  const pipeline = new Pipeline(1)

  const arr = createRequest()

  // 并发执行所有请求
  const promises = arr.map((fn, index) => {
    console.log("i", `第${index}个请求`)
    return pipeline.add(fn).then(res => {
      console.log("请求结果", res)
      return res
    })
  })
  // 等待所有请求完成
  await Promise.all(promises)

}
posted @ 2025-11-27 22:11  这样就好了  阅读(3)  评论(0)    收藏  举报