Skip to content
Search

Web Locks API

lastmod 2024-11-18created 2024-11-181 edits

The Web Locks API allows scripts running in one tab or worker to asynchronously acquire a lock, hold it while work is performed, then release it. While held, no other script executing in the same origin can acquire the same lock, which allows a web app running in multiple tabs or workers to coordinate work and the use of resources.

Features

  • The Web Locks API lets a single tab or web worker asynchronously acquire a lock, perform work, and then release the lock
  • While a lock is held, no other script in the same origin can acquire the same lock, so resources can be safely coordinated across multiple tabs or workers
  • Available only in a Secure Context (HTTPS), and usable in Web Workers

Key concepts and usage

  • A lock is an abstract resource identified by a name defined by the web application
  • For example, when multiple tabs sync IndexedDB with the network, a lock named “my_net_db_sync” can be used so that only one tab performs the sync at a time
  • Usage flow:
    • Request the lock
    • Perform the asynchronous work
    • The lock is released automatically when the work completes

Example code

navigator.locks.request("my_resource", async (lock) => {
  await do_something();
  await do_something_else();
});
  • While the lock is held, other requests for the same lock are queued, and the first request is processed once the lock is released

Options

  • mode: The default mode is “exclusive”; “shared” mode is also available. “exclusive” allows only one request, “shared” can allow many
  • ifAvailable: The request fails if the lock cannot be acquired immediately, and the callback is invoked with null
  • steal: Releases any existing lock with the same name and processes the new request first
  • signal: The request can be aborted through an AbortSignal (e.g., to implement a timeout)

Monitoring

  • navigator.locks.query() can be used to query the lock state for the current origin
  • Useful for debugging; shows which locks are held and which locks have been requested

Advanced usage

  • To explicitly control when the asynchronous work completes, a Promise can be returned
let resolve;
const p = new Promise((res) => { resolve = res });

navigator.locks.request("my_resource", (lock) => p);
  • The lock is released when resolve() is called

Avoiding deadlock

  • A deadlock is a situation where different requests conflict because of ordering and none can make progress
  • For example, if tab 1 holds lock A and tab 2 holds lock B, and then tab 1 requests lock B while tab 2 requests lock A, they wait on each other
  • To prevent this:
  • Do not nest lock requests
  • Make lock requests in a consistent order
  • Set a timeout to abort the request

Interfaces

  • Lock: Provides the name and mode of a requested lock
  • LockManager: Provides methods for requesting new locks and querying existing locks
  • An instance can be obtained via navigator.locks
  • WorkerNavigator.locks is available in Web Workers

Specification and browser support

  • Specification: Web Locks API
  • Browser compatibility: Supported only in some browsers; support in current browsers can be checked on MDN

GN⁺'s opinion

  • The Web Locks API is useful for solving resource synchronization problems in asynchronous environments
  • Deadlocks can occur, so care is needed when using it, and safeguards such as timeouts should be considered
  • Shared mode can improve performance for read-only work, but race conditions still need careful review
  • This API can serve as an alternative for solving the synchronization issues of existing localStorage or IndexedDB

See also

Favorite site

author Zer0 sitemap