LockManager: request() 方法
注意:此功能在 Web Workers 中可用。
LockManager 接口的 request() 方法用于请求一个 Lock 对象,并提供指定其名称和特性的参数。请求到的 Lock 会被传递给一个回调函数,而该方法本身会返回一个 Promise。该 Promise 会在锁释放后,随着回调函数的执行结果而解析(或拒绝),或者在请求被中止时拒绝。
options 参数的 mode 属性可以是 "exclusive"(独占)或 "shared"(共享)。
当某个代码实例应该独占资源时,请求一个 "exclusive" 锁。这适用于标签页和 worker 中的代码。使用此模式来表示对资源的互斥访问。当持有某个名称的 "exclusive" 锁时,任何其他具有相同名称的锁都无法被持有。
当多个代码实例可以共享对资源的访问时,请求一个 "shared" 锁。当持有某个名称的 "shared" 锁时,其他具有相同名称的 "shared" 锁可以被授予,但具有该名称的 "exclusive" 锁无法被持有或授予。
这种共享/独占锁模式在数据库事务架构中很常见,例如,它允许多个读取器同时访问(每个读取器请求一个 "shared" 锁),但只允许一个写入器(一个 "exclusive" 锁)。这被称为“读者-写者”模式。在 IndexedDB API 中,这表现为 "readonly" 和 "readwrite" 事务,它们具有相同的语义。
语法
request(name, callback)
request(name, options, callback)
参数
name-
您想要请求的锁的标识符。
options可选-
一个描述您想要创建的锁的特性的对象。有效值为:
mode可选-
可以是
"exclusive"(独占)或"shared"(共享)。默认值为"exclusive"。 ifAvailable可选-
如果为
true,则仅当锁尚未被持有(可用)时,才会授予锁请求。如果无法授予,回调函数将以null而非Lock实例的形式被调用。默认值为false。 steal可选-
如果为
true,则会释放所有具有相同名称的已持有锁,并授予当前请求,从而优先于任何排队中的相同请求。默认值为false。警告: 请谨慎使用!先前在锁内运行的代码将继续执行,并且可能会与当前持有锁的代码发生冲突。
signal可选-
一个
AbortSignal(AbortController的signal属性);如果指定了并且AbortController被中止,则如果锁请求尚未被授予,它将被丢弃。
回调-
在锁被授予时调用的方法。当回调函数返回(或抛出异常)时,锁会自动释放。通常回调函数是一个异步函数,这会导致只有在异步函数完全完成后锁才会被释放。
返回值
一个 Promise,它会在锁释放后、随着回调函数的执行结果而解析(或拒绝),或者在请求被中止时拒绝。
异常
此方法可能返回一个拒绝的 Promise,拒绝原因是一个 DOMException,其类型可能为以下之一:
InvalidStateErrorDOMException-
当环境的文档不完全处于活动状态时抛出。
SecurityErrorDOMException-
当无法为当前环境获取锁管理器时抛出。
NotSupportedErrorDOMException-
当
name以连字符(-)开头,同时设置了steal和ifAvailable选项为true,或者当signal选项存在且steal或ifAvailable选项之一为true时抛出。 AbortErrorDOMException-
当
signal选项存在且被中止时抛出。
示例
通用示例
以下示例展示了 request() 方法的基本用法,其中回调函数为一个异步函数。一旦回调函数被调用,此源上的任何其他正在运行的代码都无法持有 my_resource,直到回调函数返回为止。
await navigator.locks.request("my_resource", async (lock) => {
// The lock was granted.
});
mode 示例
以下示例展示了如何为读者和写者使用 mode 选项。
请注意,这两个函数都使用名为 my_resource 的锁。do_read() 请求一个 'shared' 模式的锁,这意味着跨不同事件处理程序、标签页或 worker 的多个调用可能会同时发生。
async function do_read() {
await navigator.locks.request(
"my_resource",
{ mode: "shared" },
async (lock) => {
// Read code here.
},
);
}
do_write() 函数使用相同的锁,但模式为 'exclusive',这将延迟 do_read() 中 request() 调用的执行,直到写入操作完成。这同样适用于事件处理程序、标签页或 worker。
async function do_write() {
await navigator.locks.request(
"my_resource",
{ mode: "exclusive" },
async (lock) => {
// Write code here.
},
);
}
ifAvailable 示例
要仅在锁未被占用时获取锁,请使用 ifAvailable 选项。在此函数中,await 意味着该方法在回调函数完成之前不会返回。由于该锁仅在可用时才会被授予,因此此调用避免了需要等待锁在别处被释放。
await navigator.locks.request(
"my_resource",
{ ifAvailable: true },
async (lock) => {
if (!lock) {
// The lock was not granted - get out fast.
return;
}
// The lock was granted, and no other running code in this origin is holding
// the 'my_res_lock' lock until this returns.
},
);
signal 示例
要仅为锁等待一小段时间,请使用 signal 选项。
const controller = new AbortController();
// Wait at most 200ms.
setTimeout(() => controller.abort(), 200);
try {
await navigator.locks.request(
"my_resource",
{ signal: controller.signal },
async (lock) => {
// The lock was acquired!
},
);
} catch (ex) {
if (ex.name === "AbortError") {
// The request aborted before it could be granted.
}
}
规范
| 规范 |
|---|
| Web Locks API # api-lock-manager-request |
浏览器兼容性
加载中…