Ugyanaz a webalkalmazás két fülben nem két külön világ. Mindkettő írhatja az IndexedDB-t, egyszerre ürítheti az offline küldési sort, vagy párhuzamosan futtathat drága inicializálást. Ilyenkor a localStorage-ba tett „én vagyok a vezető” jelző gyorsan versenyhelyzet, lejárati idők és félbehagyott állapotok gyűjteményévé válik.
A Web Locks API erre ad a böngésző által kezelt, originön belüli kizárást. Nem üzenetküldő csatorna, hanem zárolási sor: egy névhez kérünk jogot, a böngésző pedig csak kompatibilis kéréseket enged egyszerre futni.

A lock a callback idejére él
A belépési pont a navigator.locks.request(). A megadott név alkalmazásbeli erőforrást jelöl: lehet app:outbox-sync, app:token-refresh vagy egy dokumentum azonosítója. A névnek érdemes prefixet adni, mert ugyanazon origin minden saját oldala és workere ugyanabban a zárolási névtérben van.
A lockot nem nekünk kell feloldani. A callback által visszaadott promise lezárulásakor oldódik fel; az API specifikációja szerint ez a callback hibájánál is megtörténik. Emiatt a kritikus szakasz legyen kicsi és egyértelmű: csak az legyen benne, amit tényleg egy fülre akarunk korlátozni.
export async function syncOutboxIfLeader(flushOutbox) {
if (!("locks" in navigator)) return "no-lock-api";
return navigator.locks.request(
"app:outbox-sync",
{ ifAvailable: true },
async (lock) => {
if (lock === null) return "other-tab-is-syncing";
await flushOutbox();
return "synced";
},
);
}
A példa szándékosan nem áll sorba. Az ifAvailable: true esetén a callback azonnal null-t kap, ha másik kontextus fogja a lockot. Ez jó periodikus vagy esemény hatására induló outbox-szinkronhoz: a másik fül dolgozik, ezért ez a futás kimarad. Ha minden kérésnek sorra kell kerülnie, hagyjuk el ezt az opciót; a request promise-a akkor csak a callback és a felszabadítás után teljesül.
Fontos, hogy ez valódi aszinkron döntés, még ifAvailable mellett is: a böngészőnek más folyamatban futó fülekkel is egyeztethet. Ne olvassunk rá egy külön jelzőváltozót, és ne próbáljuk az eredményt szinkron módon kikövetkeztetni. A callback lock paramétere az egyetlen megbízható válasz arra, hogy ez a futás beléphet-e a kritikus szakaszba.
Nem csak egyetlen író létezik
Az alapértelmezett mód az exclusive: egy néven egyszerre egy holder lehet. A mode: "shared" viszont több olvasót enged, kizárólagos kérés pedig csak akkor indulhat, amikor ezek már véget értek. Ez a klasszikus olvasó–író minta, csak itt fülek és workerek között működik. A specifikáció azt is rögzíti, hogy a várakozó kérés sorrendjét a lock-kompatibilitás mellett a sor eleje korlátozza, ezért ne építsünk arra, hogy egy későbbi shared kérés „átugorja” az előtte váró exkluzív írót.
Gyakori minta a „vezető fül”: az egyik oldal hosszú ideig fogja a app:sync-leader lockot és végzi a háttérszinkront; a többi várakozik. Ha a vezető bezáródik vagy összeomlik, a környezete megszűnik, a lock felszabadul, és egy várakozó kérés megkaphatja. A Web Locks dolgozik Web Workerben is, így a koordinációt nem köti feltétlenül a felülethez.
Amit ez nem old meg
Ez nem adatbázis-tranzakció és nem elosztott lock. Az azonos originre korlátozott böngészős zárolás nem akadályozza meg, hogy két külön felhasználó, két eszköz vagy két szerverpéldány ugyanazt a szerveroldali adatot írja. Az API csak biztonságos kontextusban érhető el, ezért HTTPS kell hozzá, és éles alkalmazásban feature detection, valamint üzletileg helyes fallback szükséges.
A signal opcióval egy még várakozó kérés eldobható AbortSignal segítségével. Ezt használhatjuk lock-várakozási időkorláthoz. A steal ezzel szemben vészkapcsoló: feloldja a meglévő lockot és megelőzi a sort. A korábbi callback kódját nem állítja le, ezért olyan kritikus szakasznál, ahol a régi futás még írhat, könnyen pont azt az egyidejűséget hozzuk vissza, amit el akartunk kerülni.
A lock tehát koordinációs eszköz, nem integritási garancia. Az outbox tényleges feldolgozása legyen idempotens, a szerveroldali írás pedig továbbra is védje magát. Viszont ha eddig egy törékeny localStorage-protokoll csak azért létezett, hogy két fül ne indítsa el ugyanazt a munkát, a navigator.locks jó eséllyel egyszerűbb és megbízhatóbb alap.