Signatur
Beschreibung
Die Methode query() des Interfaces LockManager (erreichbar über navigator.locks) liefert eine Momentaufnahme aller Sperren der Web Locks API, die für den aktuellen Ursprung (Origin) existieren. Das Ergebnis ist ein LockManagerSnapshot-Objekt mit zwei Arrays:
held: Sperren, die gerade gehalten werdenpending: Sperranforderungen, die in der Warteschlange stehen
Jeder Eintrag ist ein LockInfo-Objekt mit den Eigenschaften name (Name der Ressource), mode ("exclusive" oder "shared") und clientId (Kennung des Tabs, Workers oder Frames, der die Sperre hält oder anfordert; sie passt zu Client.id in Service Workern).
Die Methode ist vor allem zum Debuggen, Überwachen und für Diagnose-Oberflächen gedacht, etwa um zu sehen, welcher Tab eine Ressource blockiert oder wie lang die Warteschlange ist. Auf das Ergebnis solltest du keine Steuerlogik aufbauen: Der Snapshot kann schon veraltet sein, wenn das Promise erfüllt wird.
Rückgabewert
Promise, das mit einem Objekt { held: LockInfo[], pending: LockInfo[] } erfüllt wird. Jedes LockInfo hat die Eigenschaften name, mode und clientId.Beispiele
Gehaltene und wartende Sperren ausgeben
const zeigeSperren = async () => {
const { held, pending } = await navigator.locks.query();
console.log(`Gehalten: ${held.length}, wartend: ${pending.length}`);
for (const lock of held) {
console.log(`HELD ${lock.name} (${lock.mode}) von ${lock.clientId}`);
}
for (const lock of pending) {
console.log(`PENDING ${lock.name} (${lock.mode}) von ${lock.clientId}`);
}
};
zeigeSperren();
Snapshot abfragen, während eine Sperre gehalten wird
const warte = (ms) => new Promise((r) => setTimeout(r, ms));
// Sperre 2 Sekunden lang halten
navigator.locks.request('cache-sync', async () => {
await warte(2000);
});
// Zweite Anforderung derselben Ressource landet in der Warteschlange
navigator.locks.request('cache-sync', async () => {
console.log('Zweite Sperre erhalten');
});
const snapshot = await navigator.locks.query();
console.log(snapshot.held.map((l) => l.name));
console.log(snapshot.pending.map((l) => l.name));
Prüfen, ob eine bestimmte Ressource belegt ist (nur zur Anzeige)
const istBelegt = async (name) => {
const { held } = await navigator.locks.query();
return held.some((lock) => lock.name === name);
};
const status = document.querySelector('#sync-status');
if (await istBelegt('db-migration')) {
status.textContent = 'Migration läuft in einem anderen Tab …';
} else {
status.textContent = 'Bereit';
}
// Wichtig · Fallstricke
- Race Condition: Das Ergebnis ist nur eine Momentaufnahme. Prüfe nicht erst mit
query()und fordere dann eine Sperre an („check-then-act“), denn dazwischen kann sich der Zustand ändern. Nutze stattdessennavigator.locks.request(name, { ifAvailable: true }, cb). Dann ist die Sperre im Callbacknull, wenn die Ressource belegt ist. - Nur in sicheren Kontexten (HTTPS oder localhost) verfügbar. Funktioniert in Fenstern und Workern, aber nicht in Frames mit opakem Ursprung (z. B.
sandboxohneallow-same-origin). Dort wird das Promise mit einemSecurityErrorabgelehnt. - Der Snapshot umfasst alle Kontexte desselben Ursprungs (Tabs, Worker), aber keine anderen Ursprünge. Welche Sperren im Snapshot erscheinen, kann je nach Browser (z. B. bei Storage-Partitionierung) abweichen.
- Die Reihenfolge in
pendingentspricht der Reihenfolge der Anforderungen. Fürheldist keine Reihenfolge garantiert. - Vor der Nutzung auf Unterstützung prüfen:
if ('locks' in navigator) { … }. Ältere Firefox-Versionen (vor 96) und Safari-Versionen (vor 15.4) kennen die API nicht.