当前位置:首页 > JavaScript

js实现并发量控制

2026-04-04 18:29:47JavaScript

实现并发量控制的方法

在JavaScript中实现并发量控制通常用于限制同时执行的异步任务数量,避免资源过载。以下是几种常见的实现方式:

使用Promise和队列控制并发

通过维护一个任务队列和当前执行的任务数来实现并发控制。当有任务完成时,从队列中取出新任务执行。

class ConcurrencyControl {
  constructor(maxConcurrency) {
    this.maxConcurrency = maxConcurrency;
    this.queue = [];
    this.running = 0;
  }

  addTask(task) {
    return new Promise((resolve, reject) => {
      const wrappedTask = () => {
        return Promise.resolve(task()).then(resolve, reject).finally(() => {
          this.running--;
          this.next();
        });
      };

      this.queue.push(wrappedTask);
      this.next();
    });
  }

  next() {
    while (this.running < this.maxConcurrency && this.queue.length) {
      const task = this.queue.shift();
      task();
      this.running++;
    }
  }
}

使用async/await和Semaphore模式

Semaphore是一种经典的并发控制模式,可以通过计数器来实现。

class Semaphore {
  constructor(max) {
    this.max = max;
    this.count = 0;
    this.waiting = [];
  }

  async acquire() {
    if (this.count < this.max) {
      this.count++;
      return;
    }
    await new Promise(resolve => this.waiting.push(resolve));
  }

  release() {
    this.count--;
    if (this.waiting.length > 0) {
      const resolve = this.waiting.shift();
      resolve();
    }
  }
}

async function controlledTask(semaphore, task) {
  await semaphore.acquire();
  try {
    return await task();
  } finally {
    semaphore.release();
  }
}

使用第三方库

许多成熟的第三方库提供了并发控制功能,如p-limitasync等。

使用p-limit示例:

const pLimit = require('p-limit');

const limit = pLimit(3); // 并发限制为3

const tasks = [
  limit(() => fetch('url1')),
  limit(() => fetch('url2')),
  // ...更多任务
];

Promise.all(tasks).then(results => {
  // 处理结果
});

使用Generator和协程

通过Generator函数和协程的概念可以实现更精细的并发控制。

js实现并发量控制

function* taskGenerator(tasks) {
  for (const task of tasks) {
    yield task();
  }
}

async function runWithConcurrency(generator, concurrency) {
  const workers = Array(concurrency).fill(null).map(async () => {
    for await (const result of generator) {
      // 处理结果
    }
  });
  await Promise.all(workers);
}

注意事项

  • 错误处理:确保每个任务都有适当的错误处理机制,避免因单个任务失败导致整个控制流程中断。
  • 资源释放:任务完成后要及时释放资源,防止内存泄漏。
  • 动态调整:某些场景可能需要动态调整并发量,可以根据系统负载实时修改最大并发数。
  • 取消机制:考虑实现任务取消功能,对于长时间运行或不再需要的任务可以中断执行。

以上方法可以根据具体需求选择或组合使用,对于简单场景推荐使用Promise队列或第三方库,复杂场景可能需要更精细的控制机制。

标签: js
分享给朋友:

相关文章

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js实现延迟

js实现延迟

实现延迟的方法 在JavaScript中,实现延迟操作有多种方式,以下是几种常见的方法: 使用setTimeout函数 setTimeout是JavaScript中最常用的延迟执行方法。它接受一个回…

js实现选题

js实现选题

实现选题功能的JavaScript方法 基础实现方案 使用数组存储选项,通过随机索引选取: const options = ['选项A', '选项B', '选项C', '选项D']; const r…

js树实现

js树实现

树的基本概念 树是一种非线性的数据结构,由节点和边组成。每个节点包含一个值和指向子节点的引用。树的顶部节点称为根节点,没有子节点的节点称为叶节点。 树的实现方式 在JavaScript中,树可以通过…

js实现视口

js实现视口

js实现视口检测的方法 使用JavaScript检测元素是否进入视口(viewport)可以通过Intersection Observer API或手动计算元素位置实现。以下是两种常见方法: Int…

js实现下拉菜单

js实现下拉菜单

使用HTML和CSS创建基础结构 HTML部分需要包含一个触发下拉的按钮和隐藏的下拉菜单内容: <div class="dropdown"> <button class="dr…