Web Locks API

Координация эксклюзивного доступа к ресурсу между вкладками/воркерами одного origin'а.

Что это

navigator.locks — захват именованного lock'а. Пока одна вкладка/воркер держит lock с именем 'sync', другие await'ят. После завершения колбека lock освобождается автоматически. Применение: чтобы только одна вкладка делала тяжёлую синхронизацию с сервером.

Базовое использование

// В нескольких вкладках одинаковый код
navigator.locks.request('db-sync', async (lock) => {
  // только одна вкладка попадёт сюда одновременно
  await syncToServer;
});

// С опциями
await navigator.locks.request('sync', { mode: 'exclusive', ifAvailable: true }, async (lock) => {
  if (!lock) {
    // не получили — кто-то держит
    return;
  }
  await heavyTask;
});

// Shared lock — несколько читателей разрешены
navigator.locks.request('cache', { mode: 'shared' }, async () => {
  await readCache;
});

// Проверить состояние
const state = await navigator.locks.query;
// state.held - кто держит, state.pending - очередь

Опции

Опция Что
mode: 'exclusive' (default) Только один владелец
mode: 'shared' Много читателей, исключают exclusive
ifAvailable: true Не ждать — если занят, колбек получит null
steal: true Отобрать насильно (для recovery)
signal: AbortSignal Прервать ожидание

Поддержка

  • Chrome/Edge 69+, Firefox 96+, Safari 15.4+
  • Доступно в Window, Worker, Service Worker
  • Secure context (HTTPS или localhost)

Подводные камни

  • Освобождение происходит автоматически при возврате из колбека — не нужно release руками
  • Если вкладка крешнулась — lock освобождается браузером
  • Между разными origin'ами не делится
  • Долгие операции под lock'ом блокируют другие вкладки — режь на чанки

Используется в bootcamp

  • В local-first архитектурах: одна вкладка — лидер-синкер
  • AsyncRace: не нужно (single-tab task)

Ссылки

🎓 Источники

См. также