Web Locks

navigator.locks is a mutex shared by all tabs and workers of an origin, Baseline Widely available. request(name, callback) waits for the lock and releases it when the callback's promise settles, so only one tab refreshes a token. Pass mode: 'shared' for concurrent readers, ifAvailable: true to receive null instead of waiting, or steal: true to take the lock by force.

Queued and conditional lock requestsJavaScript
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const save = (who) => navigator.locks.request('drafts-db', async (lock) => {
  const { pending } = await navigator.locks.query();
  console.log(`${who} holds ${lock.name} (${lock.mode}); ${pending.length} waiting`);
  await wait(100);                                 // held until this promise settles
});
save('A');
save('B');
navigator.locks.request('drafts-db', { ifAvailable: true }, (lock) => console.log('C:', lock));
Output
C: null
A holds drafts-db (exclusive); 1 waiting
B holds drafts-db (exclusive); 0 waiting

A callback that never settles blocks all other tabs, so keep locked sections short.