Signatur
Beschreibung
Ein Lock-Objekt steht für eine Sperre, die über navigator.locks.request() angefordert und erteilt wurde. Es wird an die Callback-Funktion übergeben, sobald die Sperre gehalten wird. Die Sperre bleibt so lange aktiv, bis der Callback zurückkehrt oder das von ihm zurückgegebene Promise erfüllt bzw. abgelehnt wird.
Das Interface ist bewusst schlank und hat nur zwei schreibgeschützte Eigenschaften:
Lock.name: der beim Anfordern übergebene Name der Ressource (string).Lock.mode: der Zugriffsmodus, entweder"exclusive"(Standard, nur ein Halter) oder"shared"(mehrere Leser gleichzeitig).
Web Locks koordinieren den Zugriff auf gemeinsame Ressourcen, z. B. IndexedDB-Transaktionen, Token-Aktualisierungen oder Synchronisationsvorgänge. Das funktioniert über mehrere Tabs, Fenster und Worker desselben Ursprungs (Origin) hinweg. Man erzeugt Lock-Objekte nie selbst: Sie werden ausschließlich vom LockManager bereitgestellt.
Wird ifAvailable: true gesetzt und ist die Sperre gerade belegt, erhält der Callback statt eines Lock-Objekts den Wert null. Diesen Fall sollte man immer prüfen.
Rückgabewert
LockManager an den Callback von navigator.locks.request() übergeben. Bei ifAvailable: true und belegter Sperre ist der Wert null. Eigenschaften: name: string, mode: "exclusive" | "shared".Beispiele
Exklusive Sperre anfordern und Lock-Eigenschaften lesen
await navigator.locks.request('cache-update', async (lock) => {
console.log(lock instanceof Lock); // Lock-Objekt vom LockManager
console.log(`Sperre: ${lock.name}, Modus: ${lock.mode}`);
// kritischer Abschnitt: nur ein Tab/Worker gleichzeitig
await new Promise((r) => setTimeout(r, 500));
});
console.log('Sperre freigegeben');
Gemeinsame Lesesperre (shared)
const readConfig = () =>
navigator.locks.request('config', { mode: 'shared' }, async (lock) => {
console.log(`${lock.name} gelesen im Modus ${lock.mode}`);
return JSON.parse(localStorage.getItem('config') ?? '{}');
});
// Mehrere Leser dürfen gleichzeitig zugreifen
const [a, b] = await Promise.all([readConfig(), readConfig()]);
console.log(a, b);
Nur ausführen, wenn die Sperre frei ist (ifAvailable)
const syncOnce = () =>
navigator.locks.request('sync', { ifAvailable: true }, async (lock) => {
if (!lock) {
console.log('Synchronisation läuft bereits in einem anderen Tab');
return false;
}
console.log(`Starte Sync mit Sperre "${lock.name}"`);
await fetch('/api/sync', { method: 'POST' });
return true;
});
const started = await syncOnce();
console.log('Gestartet:', started);
Gehaltene und wartende Sperren abfragen
navigator.locks.request('job', async () => {
const { held, pending } = await navigator.locks.query();
held.forEach(({ name, mode, clientId }) =>
console.log('gehalten:', name, mode, clientId)
);
console.log('wartend:', pending.length);
});
// Wichtig · Fallstricke
- Nur in sicherem Kontext: Die Web Locks API steht nur über HTTPS bzw.
localhostzur Verfügung. Sonst istnavigator.locksundefined. - Lebensdauer: Die Sperre wird freigegeben, sobald das Promise des Callbacks abgeschlossen ist, nicht erst, wenn das
Lock-Objekt vom Garbage Collector entfernt wird. Gibt der Callback kein Promise zurück, wird die Sperre sofort nach der synchronen Ausführung wieder freigegeben. Ein Promise, das nie abschließt, hält die Sperre dauerhaft und blockiert alle anderen Anforderungen (Deadlock-Gefahr). nullbeiifAvailable: Ist die Sperre belegt, wird der Callback mitnullaufgerufen. Werlock.nameohne Prüfung liest, bekommt einenTypeError.- Keine Konstruktion:
new Lock()wirft einenTypeError, denn Instanzen entstehen nur über denLockManager. - Geltungsbereich: Sperren gelten nur innerhalb desselben Ursprungs (Origin) und derselben Storage-Partition. Sie koordinieren nicht über Geräte oder Server hinweg.
- Namen, die mit
-beginnen, sind reserviert und führen zu einemNotSupportedError. - Verfügbar in Fenstern und Workern. In Node.js gibt es die API erst ab Version 22 (experimentell); in älteren Umgebungen vorher auf
'locks' in navigatorprüfen.