@chriscdn/promise-semaphore

中文文档
4.0.1发布于 2026/09/14MITTypeScriptES Module零依赖近 30 天下载 6709

限制或节奏同步代码在事件循环的单独迭代中同步执行.

中文使用文档
文档目录15 节
  1. 安装
  2. 版本 3
  3. API - 司马彪
  4. 创建实例
  5. 获取锁
  6. 释放锁
  7. 检查能否获取锁
  8. count
  9. request 方法
  10. requestIfAvailable 方法
  11. 实例1
  12. 实例2
  13. API - 组合Semaphore
  14. 示例
  15. 许可证

@chriscdn/ 保证- semaphore

单独限制或节制同步代码的同步执行 事件循环的重复.

安装

使用 npm :

npm install @chriscdn/promise-semaphore

版本 3

第3版引入了两个主要变化:

  • 一个新的 GroupSemaphore 分类已添加。 它允许同一组内(由密钥所识别)的多个任务同时运行,同时确保一次只有一个组的任务活动. 详情见下文.
  • 默认导出已被命名为导出 .

更改 :

import Semaphore from "@chriscdn/promise-semaphore";

改为:

import { Semaphore } from "@chriscdn/promise-semaphore";

API - 司马彪

创建实例

import { Semaphore } from "@chriscdn/promise-semaphore";
const semaphore = new Semaphore([maxConcurrent]);

这个 maxConcurrent 参数是可选的,默认为 1 (使它成为独家锁或 二进制分母) (中文(简体) ). 一个大于 1 可用于允许多起同时行刑,避免事件循环的重复.

获取锁

semaphore.acquire([options]);

此方法返回 a Promise 当锁被获取时,它就能解决.

这个 options 参数是可选的,可以是:

  • A 类 键 (单位:千美元)string 或者说 number: 这让一个单身 Semaphore 实例 key (用法).
  • 一个 对象 具有下列属性(所有可选):
    • key (单位:千美元)string 或者说 number:功能与以上相同.
    • priority (单位:千美元)number:确定排队请求的处理顺序. 高值首先处理.

释放锁

semaphore.release([key]);

这个 release 方法应在 finally 块(无论是使用承诺还是使用 try/catch block),以确保解锁. 打电话很重要 release 同样的 key 锁是用它买的.

检查能否获取锁

semaphore.canAcquire([key]);

此同步方法返回 true 如果一个锁可以立即获得 false 否则.

count

semaphore.count([key]);

此函数是同步的, 并返回当前锁定数 .

request 方法

const results = await semaphore.request(fn [, options]);

此函数在使用时会减少锅炉板 acquire 财务报告和审定财务报表 release。它返回一个承诺,当 fn 完成 。 它在功能上相当于:

try {
  await semaphore.acquire([options]);
  return await fn();
} finally {
  semaphore.release([key]);
}

requestIfAvailable 方法

const results = await semaphore.requestIfAvailable(fn [, options]);

这在功能上相当于:

return semaphore.canAcquire([key])
  ? await semaphore.request(fn, [options])
  : null;

在只运行一个函数块的一例同时放弃其他尝试的情况下,这样做是有用的。 例如,处理重复按钮点击.

实例1

import { Semaphore } from "@chriscdn/promise-semaphore";
const semaphore = new Semaphore();

// Using promises
semaphore
  .acquire()
  .then(() => {
    // This block executes once a lock is acquired.
    // If already locked, it waits and executes after all preceding locks are released.
    //
    // Critical operations
  })
  .finally(() => {
    // The lock is released, allowing the next queued block to proceed.
    semaphore.release();
  });

// Using async/await
try {
  await semaphore.acquire();

  // Critical operations
} finally {
  semaphore.release();
}

// Using the request function
await semaphore.request(() => {
  // Critical operations
});

实例2

考虑将文件下载并保存到磁盘的同步函数 :

const downloadAndSave = async (url) => {
  const filePath = urlToFilePath(url);

  if (await pathExists(filePath)) {
    // The file is already on disk, so no action is required.
    return filePath;
  }

  await downloadAndSaveToFilepath(url, filePath);
  return filePath;
};

这种办法在下列日期之前按预期有效: downloadAndSave() 以相同的快速相继方式调用多次 url。如果没有控制,它可以同时启动试图同时写入同一文件的下载.

这个问题可以通过使用 Semaphore 与 key 参数 :

import { Semaphore } from "@chriscdn/promise-semaphore";
const semaphore = new Semaphore();

const downloadAndSave = async (url) => {
  try {
    await semaphore.acquire(url);

    // This block continues once a lock on url is acquired. This
    // permits multiple simultaneous downloads for different urls.

    const filePath = urlToFilePath(url);

    if (await pathExists(filePath)) {
      // the file is on disk, so no action is required
    } else {
      await downloadAndSaveToFilepath(url, filePath);
    }

    return filePath;
  } finally {
    semaphore.release(url);
  }
};

通过使用以下方法可以取得同样的结果: request 函数 :

const downloadAndSave = (url) => {
  return semaphore.request(async () => {
    const filePath = urlToFilePath(url);

    if (await pathExists(filePath)) {
      // The file is already on disk, so no action is required.
    } else {
      await downloadAndSaveToFilepath(url, filePath);
    }
    return filePath;
  }, url);
};

API - 组合Semaphore

这个 GroupSemaphore 类管理不同的 semapore 组 任务。 一个小组由密钥确定,semaphore确保每次只有一个小组能够执行它的任务. 组内的任务可以同时运行.

这个 GroupSemaphore 班级曝光 acquire 财务报告和审定财务报表 release 方法,其接口与 Semaphore。唯一的区别是 key 需要参数.

示例

import { GroupSemaphore } from "@chriscdn/promise-semaphore";

const groupSemaphore = new GroupSemaphore();

const RunA = async () => {
  try {
    await groupSemaphore.acquire("GroupA");

    // Perform asynchronous operations for group A
  } finally {
    groupSemaphore.release("GroupA");
  }
};

const RunB = async () => {
  try {
    await groupSemaphore.acquire("GroupB");

    // Perform asynchronous operations for group B
  } finally {
    groupSemaphore.release("GroupB");
  }
};

此设置允许 RunA ,并同时运行。 但是,打电话 RunB 将等到所有 GroupA 任务在获取锁定之前完成 GroupB。一旦 GroupB 获取锁,任何后续呼叫 RunA 将等到 GroupB 执行前释放锁.

许可证

麻省理工学院

版本与发布记录

@chriscdn/promise-semaphore 共发布 25 个版本,首次发布于 2020/04/14;过去 12 个月发布了 3 个版本。

版本发布日期距今
4.0.1latest2026/09/141 个月前
4.0.02026/02/218 个月前
3.1.32026/02/208 个月前
3.1.22025/11/031 年前
3.1.12025/08/271.2 年前
3.0.12025/05/051.5 年前

关于 @chriscdn/promise-semaphore 的常见问题

@chriscdn/promise-semaphore 是什么?

限制或节奏同步代码在事件循环的单独迭代中同步执行.

如何安装 @chriscdn/promise-semaphore?

在项目目录运行 npm install @chriscdn/promise-semaphore,或使用 pnpm add / yarn add / bun add。

@chriscdn/promise-semaphore 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@chriscdn/promise-semaphore 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@chriscdn/promise-semaphore 可以商用吗?

@chriscdn/promise-semaphore 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@chriscdn/promise-semaphore 的下载量有多少?

根据 npm 官方下载统计,@chriscdn/promise-semaphore 在 2026/10/10 – 2026/11/08 这 30 天内被下载 6,709 次,日均约 224 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@chriscdn/promise-semaphore 还在维护吗?

最新版本 4.0.1 发布于 2026/09/14(1 个月前);至今共发布 25 个版本,其中过去 12 个月发布了 3 个;首次发布于 2020/04/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。