蓝天

chatGPT的js信号量实现

信号量类

在 JavaScript 中,可以使用 Promise 和 async/await 来模拟信号量,下面是一个简单的信号量实现:

class Semaphore {
  constructor(maxConcurrency) {
    this.maxConcurrency = maxConcurrency;
    this.currentConcurrency = 0;
    this.queue = [];
  }

  async acquire() {
    return new Promise((resolve) => {
      const tryAcquire = () => {
        if (this.currentConcurrency < this.maxConcurrency) {
          this.currentConcurrency++;
          resolve();
        } else {
          this.queue.push(tryAcquire);
        }
      };
      tryAcquire();
    });
  }

  release() {
    this.currentConcurrency--;
    if (this.queue.length > 0) {
      const next = this.queue.shift();
      next();
    }
  }

  async withLock(task) {
    await this.acquire();
    try {
      await task();
    } finally {
      this.release();
    }
  }
}

这个 Semaphore 类有一个构造函数,它接受一个参数 maxConcurrency,表示允许的最大并发数。acquire 方法尝试获取信号量,如果当前并发数小于最大并发数,它将立即解析。否则,它将等待直到有可用的信号量。release 方法释放信号量并唤醒等待队列中的下一个任务。withLock 方法是一个方便的包装器,它自动获取和释放信号量。

使用示例

const semaphore = new Semaphore(3); // 最大并发数为 3

async function doTask(taskId) {
  console.log(`Task ${taskId} started`);
  await new Promise((resolve) => setTimeout(resolve, 1000));
  console.log(`Task ${taskId} finished`);
}

async function main() {
  const tasks = [];
  for (let i = 0; i < 10; i++) {
    tasks.push(semaphore.withLock(() => doTask(i)));
  }
  await Promise.all(tasks);
}

main();

在这个例子中,创建了一个信号量,最大并发数为 3。然后定义了一个异步函数 doTask,它模拟一个耗时的任务。在 main 函数中,创建了 10 个任务,并使用 withLock 方法确保最多只有 3 个任务同时运行。最后,等待所有任务完成。

posted on 2023-08-28 18:20  #蓝天  阅读(29)  评论(0编辑  收藏  举报

导航