Signatur
Beschreibung
navigator.locks ist der Einstiegspunkt der Web Locks API. Die Eigenschaft ist schreibgeschützt und gibt ein LockManager-Objekt zurück. Es hat zwei Methoden: request() fordert eine benannte Sperre an, query() liefert eine Momentaufnahme der gehaltenen und wartenden Sperren.
Web Locks koordinieren den Zugriff auf gemeinsam genutzte Ressourcen wie IndexedDB, localStorage oder einen Netzwerk-Sync über alle Tabs, Fenster und Worker desselben Ursprungs hinweg. Typische Fälle: Nur ein Tab soll eine WebSocket-Verbindung halten („Leader Election“), eine Datenbankmigration darf nur einmal laufen, oder Schreibzugriffe sollen nacheinander statt gleichzeitig passieren.
Eine Sperre gilt so lange, bis das Promise, das der Callback von request() zurückgibt, erfüllt oder abgelehnt ist. Danach wird sie automatisch freigegeben. Schließt man den Tab oder beendet den Worker, gibt der Browser die Sperre ebenfalls frei. Mit dem Modus "shared" können mehrere Leser dieselbe Sperre gleichzeitig halten, "exclusive" (Standard) lässt nur einen Halter zu.
In Workern steht dieselbe Schnittstelle als WorkerNavigator.locks (self.navigator.locks) zur Verfügung.
Rückgabewert
LockManager-Objekt des aktuellen Ursprungs mit den Methoden request(name, [options], callback) und query().Beispiele
Exklusive Sperre für einen kritischen Abschnitt
const saveDraft = async (draft) => {
// Nur ein Tab gleichzeitig darf den Entwurf schreiben
return navigator.locks.request('draft-storage', async (lock) => {
console.log(`Sperre erhalten: ${lock.name} (${lock.mode})`);
const current = JSON.parse(localStorage.getItem('drafts') ?? '[]');
current.push(draft);
localStorage.setItem('drafts', JSON.stringify(current));
return current.length;
});
};
const count = await saveDraft({ text: 'Hallo Welt' });
console.log('Anzahl Entwürfe:', count);
Leader Election: nur ein Tab hält die WebSocket-Verbindung
const becomeLeader = () =>
navigator.locks.request('ws-leader', async () => {
console.log('Dieser Tab ist jetzt Leader');
const ws = new WebSocket('wss://example.com/live');
// Sperre halten, bis die Verbindung geschlossen wird
await new Promise((resolve) => ws.addEventListener('close', resolve));
console.log('Verbindung beendet, Sperre wird freigegeben');
});
becomeLeader(); // weitere Tabs warten automatisch, bis der Leader wegfällt
Nicht warten: ifAvailable und Abbruch per AbortSignal
// Sofort aufgeben, wenn die Sperre belegt ist
await navigator.locks.request('sync', { ifAvailable: true }, async (lock) => {
if (!lock) {
console.log('Sync läuft bereits in einem anderen Tab');
return;
}
console.log('Starte Sync …');
});
// Höchstens 2 Sekunden auf die Sperre warten
try {
await navigator.locks.request(
'sync',
{ signal: AbortSignal.timeout(2000) },
async () => console.log('Sync nach Wartezeit gestartet')
);
} catch (err) {
if (err.name === 'TimeoutError') console.log('Zeitüberschreitung beim Warten');
}
Sperrzustand mit query() untersuchen
if ('locks' in navigator) {
const { held, pending } = await navigator.locks.query();
held.forEach((l) => console.log('Gehalten:', l.name, l.mode));
pending.forEach((l) => console.log('Wartend:', l.name, l.mode));
} else {
console.log('Web Locks API nicht verfügbar');
}
// Wichtig · Fallstricke
- Nur in sicheren Kontexten (HTTPS oder
localhost): Auf unsicheren Seiten istnavigator.locksundefined. Vorher mit'locks' in navigatorprüfen. - Die Sperre wird erst freigegeben, wenn das vom Callback zurückgegebene Promise abgeschlossen ist. Gibt der Callback ein nie endendes Promise zurück, bleibt die Sperre dauerhaft belegt. Ein vergessenes
awaitim Callback führt dagegen dazu, dass die Sperre zu früh freigegeben wird. - Deadlocks sind möglich, wenn man Sperren ineinander verschachtelt und dabei in unterschiedlicher Reihenfolge anfordert. Der Browser erkennt sie nicht.
- Sperrnamen, die mit
-beginnen, sind reserviert und lösen einenNotSupportedErroraus.ifAvailableundsteallassen sich nicht zusammen verwenden. Beide sind auch nicht mitsignalkombinierbar. steal: truegibt bestehende Sperren gewaltsam frei. Derenrequest()-Promise wird dann mit einemAbortErrorabgelehnt. Das ist nur für Notfall-Wiederherstellung gedacht.- Sperren gelten pro Ursprung und Speicherpartition. Zwischen verschiedenen Ursprüngen oder einem normalen und einem privaten Fenster gibt es keine Koordination.
- Ältere Browser (Safari vor 15.4, Firefox vor 96) unterstützen die API nicht. Dort braucht man einen Fallback, z. B. über
BroadcastChanneloderstorage-Events.