LockManager: метод request()
Базовая реализация Широко поддерживается
Эта функция хорошо отработана и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с марта 2022 года.
Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS), в некоторых или во всех поддерживающих браузерах.
Примечание: Эта функция доступна в Web Workers.
Метод request() интерфейса LockManager запрашивает объект Lock с параметрами, определяющими его имя и характеристики. Запрашиваемый Lock передаётся в коллбэк, а сама функция возвращает Promise, который разрешается (или отклоняется) результатом коллбэка после освобождения блокировки или отклоняется, если запрос прерван.
Свойство mode параметра options может быть либо "exclusive", либо "shared".
Запросите "exclusive" блокировку, когда она должна удерживаться только одной кодовой единицей за раз. Это относится к коду как во вкладках, так и в работниках. Используйте это для представления взаимного исключения доступа к ресурсу. Когда "exclusive" блокировка с данным именем удерживается, никакая другая блокировка с тем же именем не может быть удержана.
Запросите "shared" блокировку, когда несколько экземпляров кода могут совместно использовать доступ к ресурсу. Когда "shared" блокировка с определенным именем удерживается, другим "shared" блокировкам с тем же именем могут быть предоставлены права доступа, но никакие "exclusive" блокировки с этим именем не могут быть удержаны или предоставлены.
Эта модель совместного/исключительного блокирования часто используется в архитектуре баз данных с транзакциями, например, чтобы разрешить несколько одновременных читателей (каждый запрашивает "shared" блокировку), но только одного писателя (одна "exclusive" блокировка). Это известно как паттерн «читатели-писатели». В API IndexedDB это реализовано как "readonly" и "readwrite" транзакции с одинаковой семантикой.
Синтаксис
request(name, callback) request(name, options, callback)
Параметры
name-
Идентификатор блокировки, которую вы хотите запросить.
optionsНеобязательно-
Объект, описывающий характеристики блокировки, которую вы хотите создать. Допустимые значения:
modeНеобязательно-
Either
"exclusive"или"shared". Значение по умолчанию"exclusive". ifAvailableНеобязательно-
Если
true, запрос блокировки будет выполнен только в том случае, если она не удерживается. Если её нельзя предоставить, коллбэк будет вызван сnullвместо экземпляраLock. Значение по умолчаниюfalse. stealНеобязательно-
Если
true, то все удерживаемые блокировки с тем же именем будут освобождены, и запрос будет удовлетворён, опережая любые очереди запросов на неё. Значение по умолчаниюfalse.Предупреждение: Используйте с осторожностью! Код, который ранее выполнялся внутри блокировки, продолжает выполняться и может вступить в конфликт с кодом, который теперь удерживает блокировку.
signalНеобязательно-
Объект
AbortSignal(свойствоsignalобъектаAbortController); если указано и объектAbortControllerпрерван, запрос на блокировку отбрасывается, если она ещё не получена.
callback-
Метод, вызываемый при получении блокировки. Блокировка автоматически освобождается при возврате из коллбэка (или при возникновении исключения). Обычно коллбэк является асинхронной функцией, что приводит к освобождению блокировки только после полного завершения асинхронной функции.
Возвращаемое значение
A 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', что означает, что несколько вызовов могут произойти одновременно в разных обработчиках событий, вкладках или работниках.
async function do_read() {
await navigator.locks.request(
"my_resource",
{ mode: "shared" },
async (lock) => {
// Read code here.
},
);
}
Функция do_write() использует ту же блокировку, но в режиме 'exclusive', что задержит вызов функции request() в do_read() до завершения операции записи. Это относится к различным обработчикам событий, вкладкам или работникам.
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 |
Совместимость с браузерами
| Рабочий стол | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
request |
69 | 79 | 96 | 56 | 15.4 | 69 | 96 | 48 | 15.4 | 10.0 | 69 |
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request