Web Locks API
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Dieses Feature ist verfügbar in Web Workers.
Die Web Locks API ermöglicht Skripten, die in einem Tab oder Worker ausgeführt werden, asynchron eine Sperre zu erwerben, sie zu halten, während Arbeit verrichtet wird, und sie dann freizugeben. Solange die Sperre gehalten wird, kann kein anderes Skript, das im selben Ursprung ausgeführt wird, dieselbe Sperre erwerben. Dies ermöglicht es einer Webanwendung, die in mehreren Tabs oder Workern läuft, Arbeit und Ressourcennutzung zu koordinieren.
Konzepte und Verwendung
Eine Sperre ist ein abstraktes Konzept, das eine möglicherweise gemeinsam genutzte Ressource darstellt, die von der Webanwendung durch einen selbst gewählten Namen identifiziert wird. Beispielsweise, wenn eine Webanwendung, die in mehreren Tabs läuft, sicherstellen will, dass nur ein Tab Daten zwischen dem Netzwerk und dem Indexed DB synchronisiert, könnte jeder Tab versuchen, eine "my_net_db_sync"-Sperre zu erwerben, aber nur ein Tab wird Erfolg haben (das Leader Election Muster.)
Die API wird wie folgt verwendet:
- Die Sperre wird angefordert.
- Arbeit wird während des Haltens der Sperre in einer asynchronen Aufgabe durchgeführt.
- Die Sperre wird automatisch freigegeben, wenn die Aufgabe abgeschlossen ist.
navigator.locks.request("my_resource", async (lock) => {
// The lock has been acquired.
await do_something();
await do_something_else();
// Now the lock will be released.
});
Während eine Sperre gehalten wird, werden Anforderungen für dieselbe Sperre aus diesem Ausführungskontext oder von anderen Tabs/Workern in eine Warteschlange gestellt. Die erste Anfrage in der Warteschlange wird nur gewährt, wenn die Sperre freigegeben wird.
Die API bietet optionale Funktionalitäten, die nach Bedarf genutzt werden können, darunter:
- Rückgabe von Werten aus der asynchronen Aufgabe
- geteilte und exklusive Sperrmodi
- bedingtes Erwerben
- Diagnostik zur Abfrage des Zustands von Sperren in einem Ursprung
- ein Notausgang zum Schutz vor Deadlocks
Sperren sind an Ursprünge gebunden; die von einem Tab von https://example.com
erworbenen Sperren haben keinen Einfluss auf die von einem Tab von https://example.org:8080
erworbenen Sperren, da sie unterschiedliche Ursprünge sind.
Der Haupteinstiegspunkt ist navigator.locks.request()
, der eine Sperre anfordert. Er nimmt einen Sperrnamen, einen optionalen Satz von Optionen und eine Rückruffunktion an. Die Rückruffunktion wird aufgerufen, wenn die Sperre gewährt wird. Die Sperre wird automatisch freigegeben, sobald die Rückruffunktion zurückkehrt. Daher ist die Rückruffunktion in der Regel eine async function, die bewirkt, dass die Sperre nur freigegeben wird, wenn die async-Funktion vollständig abgeschlossen ist.
Die Methode request()
gibt selbst ein Promise zurück, das aufgelöst wird, sobald die Sperre freigegeben wurde; innerhalb einer async Funktion kann ein Skript await
verwenden, um den asynchronen Code linear fließen zu lassen.
Zum Beispiel:
await do_something_without_lock();
// Request the lock.
await navigator.locks.request("my_resource", async (lock) => {
// The lock has been acquired.
await do_something_with_lock();
await do_something_else_with_lock();
// Now the lock will be released.
});
// The lock has been released.
await do_something_else_without_lock();
Optionen
Beim Anfordern einer Sperre können mehrere Optionen übergeben werden:
mode
: Der Standardmodus ist "exclusive", aber "shared" kann spezifiziert werden. Es kann nur einen "exclusive"-Halter einer Sperre geben, aber mehrere "shared"-Anfragen können gleichzeitig gewährt werden. Dies kann verwendet werden, um das Readers-Writer Muster zu implementieren.ifAvailable
: Wenn angegeben, schlägt die Sperranfrage fehl, wenn die Sperre nicht sofort, ohne zu warten, gewährt werden kann. Die Rückruffunktion wird mitnull
aufgerufen.steal
: Wenn angegeben, werden alle gehaltenen Sperren mit demselben Namen freigegeben, und die Anfrage wird gewährt, wobei alle in der Warteschlange stehenden Anfragen vorrangig abgewiesen werden.signal
: EinAbortSignal
kann übergeben werden, um eine Sperranfrage abzubrechen. Dies kann verwendet werden, um eine Zeitüberschreitung bei Anfragen zu implementieren.
Überwachung
Die Methode navigator.locks.query()
kann von Skripten verwendet werden, um den Zustand des Sperrmanagers für den Ursprung zu inspizieren. Dies kann nützlich sein, wenn man z.B. herausfinden möchte, warum eine Sperre nicht erworben werden konnte. Die Ergebnisse sind eine Momentaufnahme des Zustands des Sperrmanagers, die zu einem bestimmten Zeitpunkt gehaltene und angeforderte Sperren sowie einige zusätzliche Daten (z.B. Modus) über jede Sperre identifiziert.
Fortgeschrittene Nutzung
Für komplexere Fälle, wie das Halten der Sperre für eine beliebige Zeitdauer, kann der Rückruf ein Promise zurückgeben, das explizit durch das Skript aufgelöst wird:
// Capture promise control functions:
const { promise, resolve, reject } = Promise.withResolvers();
// Request the lock:
navigator.locks.request(
"my_resource",
// Lock is acquired.
(lock) => promise, // Now lock will be held until either resolve() or reject() is called.
);
Deadlocks
Ein Deadlock tritt auf, wenn ein Prozess nicht mehr weiterkommt, weil jeder Teil auf eine Anforderung wartet, die nicht erfüllt werden kann. Dies kann mit dieser API in komplexen Anwendungsfällen auftreten, z.B. wenn mehrere Sperren in der falschen Reihenfolge angefordert werden. Wenn Tab 1 die Sperre A hält und Tab 2 die Sperre B hält, dann versucht Tab 1 außerdem, die Sperre B zu erwerben, und Tab 2 versucht außerdem, die Sperre A zu erwerben, keine der Anforderungen kann gewährt werden. Webanwendungen können dies durch verschiedene Strategien vermeiden, z.B. indem sichergestellt wird, dass Sperranfragen nicht verschachtelt sind, immer gut geordnet sind oder Zeitüberschreitungen haben. Beachten Sie, dass solche Deadlocks nur die Sperren selbst und den auf ihnen beruhenden Code betreffen; der Browser, andere Tabs und andere Skripte auf der Seite sind nicht betroffen.
Schnittstellen
Lock
-
Stellt den Namen und den Modus einer zuvor angeforderten Sperre bereit, die im Rückruf an
LockManager.request()
empfangen wird. LockManager
-
Bietet Methoden zum Anfordern eines neuen
Lock
-Objekts und zum Abfragen eines vorhandenenLock
-Objekts. Um eine Instanz vonLockManager
zu erhalten, rufen Sienavigator.locks
auf.
Erweiterungen zu anderen Schnittstellen
-
Gibt ein
LockManager
-Objekt zurück, das Methoden zum Anfordern eines neuenLock
-Objekts und zum Abfragen eines vorhandenenLock
-Objekts bietet. -
Gibt ein
LockManager
-Objekt zurück, das Methoden zum Anfordern eines neuenLock
-Objekts und zum Abfragen eines vorhandenenLock
-Objekts bietet.
Spezifikationen
Specification |
---|
Web Locks API |
Browser-Kompatibilität
api.LockManager
BCD tables only load in the browser
api.Lock
BCD tables only load in the browser