请求池

57 阅读1分钟

写法1



  // 执行任务并控制并发数
  async function executeWithConcurrency(tasks, maxConcurrency) {
    const results = [];
    const executing = [];
    
    for (const task of tasks) {
      // 创建任务执行器
      const executor = task().then(result => {
        results.push(result);
        executing.splice(executing.indexOf(executor), 1);
      });
      
      executing.push(executor);
      
      // 控制并发数
      if (executing.length >= maxConcurrency) {
        await Promise.race(executing);
      }
    }
    
    // 等待所有任务完成
    await Promise.all(executing);
    return results;
  }

测试

function getDate(name: any) {
  return new Promise((resolve) => {
    let timer = setTimeout(() => {
      const res = `任务${name}完成`
      console.log(res)
      resolve(res);
      clearTimeout(timer);
    }, 1000);
  });
}

const tasks = []
const maxConcurrency = 2

tasks.push(() => getDate(1));
tasks.push(() => getDate(2));
tasks.push(() => getDate(3));
tasks.push(() => getDate(4));
tasks.push(() => getDate(5));
tasks.push(() => getDate(6));
tasks.push(() => getDate(7));
tasks.push(() => getDate(8));

executeWithConcurrency(tasks, maxConcurrency).then(res => {
    console.log(res)
})

写法2


v1

class SuperTask {

  private tasks = []
  private max: number
  private count = 0

  constructor(max=2) {
    this.max = max
  }

  add(fn: () => Promise<any>) {
    return new Promise((resolve, reject) => {
      this.tasks.push({fn, resolve, reject})
      this.run()
    })
  }

  private run() {
    while(this.tasks.length && this.count < this.max) {
      const {fn, resolve, reject} = this.tasks.shift()
      this.count++
      fn().then(resolve, reject).finally(() => {
        this.count--
        this.run()
      })
    }
  }
}

测试

function getDate(name: any) {
  return new Promise((resolve) => {
    let timer = setTimeout(() => {
      resolve(`任务${name}完成`);
      clearTimeout(timer);
    }, 1000);
  });
}

const superTask = new SuperTask(2);
superTask.add(() => getDate(1)).then(res => console.log(res));
superTask.add(() => getDate(2)).then(res => console.log(res));
superTask.add(() => getDate(3)).then(res => console.log(res));
superTask.add(() => getDate(4)).then(res => console.log(res));
superTask.add(() => getDate(5)).then(res => console.log(res));
superTask.add(() => getDate(6)).then(res => console.log(res));
superTask.add(() => getDate(7)).then(res => console.log(res));
superTask.add(() => getDate(8)).then(res => console.log(res));

v2: 支持普通函数并发

type Fn = (...args: any[]) => void;

type Task = {
  cb: Fn;
  resolve: Fn;
  reject: Fn;
};

class SuperTask {
  max: number;
  tasks: Task[] = [];
  count = 0;

  constructor(max = 3) {
    this.max = max;
  }

  add(cb: Fn) {
    return new Promise((resolve, reject) => {
      this.tasks.push({ cb, resolve, reject });
      this.run();
    });
  }

  run() {
    while (this.tasks.length && this.count < this.max) {
      const { cb, resolve, reject } = this.tasks.shift()!;
      this.count++;
      Promise.resolve()
        .then(cb)
        .then(resolve, reject)
        .finally(() => {
          this.count--;
          this.run();
        });
    }
  }
}