LockManager: request() 方法
注意:此功能在 Web 工作线程 中可用。
request()
方法是 LockManager
接口的方法,用于请求一个 Lock
对象,其参数指定了锁的名称和特征。请求的 Lock
会传递给回调函数,而该函数本身会返回一个 Promise
,该 Promise 在锁释放后会使用回调函数的结果来解析(或拒绝),如果请求被中止,则会拒绝。
options
参数的 mode
属性可以是 "exclusive"
或 "shared"
。
当应仅由一个代码实例同时持有锁时,请求 "exclusive"
锁。这适用于标签和工作线程中的代码。使用此方法来表示对资源的互斥访问。当持有给定名称的 "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
(signal
属性为AbortController
);如果指定并AbortController
被中止,则锁请求将被丢弃,前提是它尚未被授予。
callback
-
当授予锁时调用的方法。当回调函数返回(或抛出异常)时,锁会自动释放。通常,回调函数是一个异步函数,这会导致锁仅在异步函数完全完成时才释放。
返回值
一个 Promise
,在锁释放后使用回调函数的结果来解析(或拒绝),如果请求被中止,则会拒绝。
异常
此方法可能会返回一个被拒绝的 Promise,其中包含以下类型之一的 DOMException
InvalidStateError
DOMException
-
如果环境文档未完全激活,则抛出此异常。
SecurityError
DOMException
-
如果无法为当前环境获取锁管理器,则抛出此异常。
NotSupportedError
DOMException
-
如果
name
以连字符 (-
) 开头,选项steal
和ifAvailable
都为true
,或者选项signal
存在,且选项steal
或ifAvailable
为true
,则抛出此异常。 AbortError
DOMException
-
如果选项
signal
存在且被中止,则抛出此异常。
示例
一般示例
以下示例展示了使用 request()
方法的基本用法,其中回调函数是一个异步函数。一旦调用回调函数,在此源上的其他任何运行代码都不能持有 my_resource
,直到回调函数返回。
await navigator.locks.request("my_resource", async (lock) => {
// The lock was granted.
});
mode
示例
以下示例展示了如何使用 mode
选项来进行读写操作。
请注意,这两个函数都使用名为 my_resource
的锁。do_read()
请求 'shared'
模式的锁,这意味着多个调用可以在不同的事件处理程序、标签或工作线程中同时发生。
async function do_read() {
await navigator.locks.request(
"my_resource",
{ mode: "shared" },
async (lock) => {
// Read code here.
},
);
}
do_write()
函数使用相同的锁,但使用 'exclusive'
模式,这将延迟 do_read()
中的 request()
调用的调用,直到写入操作完成。这适用于事件处理程序、标签或工作线程。
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 锁 API # api-lock-manager-request |
浏览器兼容性
BCD 表格仅在启用了 JavaScript 的浏览器中加载。