@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 执行前释放锁.