Start · Sprachen · JavaScript · Referenz · LockManager.query()

LockManager.query()

Methode

Gibt ein <code>Promise</code> zurück, das mit einem <code>LockManagerSnapshot</code> erfüllt wird: den aktuell gehaltenen und den wartenden Sperren des Ursprungs.

seit JavaScript Baseline 2022: Chrome 69, Edge 79, Firefox 96, Saf Kategorie: webapi

Signatur

LockManager.prototype.query()

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 werden
  • pending: 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

Typ
Promise<LockManagerSnapshot>
Beschreibung
Ein 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();
Gehalten: 0, wartend: 0

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));
["cache-sync"] ["cache-sync"] Zweite Sperre erhalten

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 stattdessen navigator.locks.request(name, { ifAvailable: true }, cb). Dann ist die Sperre im Callback null, 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. sandbox ohne allow-same-origin). Dort wird das Promise mit einem SecurityError abgelehnt.
  • 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 pending entspricht der Reihenfolge der Anforderungen. Für held ist 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.