# Web Locks API：协调独占与共享工作

> navigator.locks.request() 如何授予独占或共享的命名锁以协调跨同源上下文的工作，及其存储桶作用域与安全上下文限制。

import CompatTable from '@components/CompatTable.astro';

**一句话:** Web Locks API 的 `navigator.locks.request()` 方法异步请求一个命名锁，在持有该锁期间运行回调，并在回调结束后释放锁，让不同标签页或 worker 中的脚本协调对共享资源的访问。

## 请求一个锁

```js
await navigator.locks.request('my_resource', async (lock) => {
  // 同一时刻只有一个持有者能获得名为 'my_resource' 的独占锁。
  await doWork();
});
```

## 独占锁与共享锁

根据规范，请求锁时默认 `mode: 'exclusive'`：当一个独占锁被持有时，同名的其他锁请求不会被授予。`shared` 锁则不同——多个针对同一名称的 `shared` 请求可以同时被授予，而针对该名称的 `exclusive` 请求仍需等待：

```js
await navigator.locks.request('my_resource', { mode: 'shared' }, async () => {
  await readSharedData();
});
```

独占锁只能阻止另一个同样通过该 API 协作的调用方获取同名锁——它无法阻止绕过 `navigator.locks` 的代码直接读写底层资源。

## 作用域：共享存储桶的代理

MDN 将锁描述为协调同源的标签页和 worker。规范的表述更精确：协作式协调发生在共享同一存储桶（storage bucket）的一组代理之间，这可能跨越多个代理集群（agent cluster）。因此，最终落在不同存储分区或存储桶中的上下文，即使同源，也不保证共享同一个锁管理器。

## 浏览器与生态支持

<CompatTable feature="web-locks" />

## 运行时检测与降级

```js
async function withResourceLock(name, fn) {
  if (!('locks' in navigator)) {
    // 不支持 Web Locks：不请求锁，直接运行回调。
    return fn();
  }
  return navigator.locks.request(name, fn);
}
```

## 实践清单

- [ ] 根据 MDN，该 API 限于安全上下文（HTTPS），规范也将其标记为 `SecureContext`。
- [ ] 规范允许应用自行选择锁的命名方案，但以 U+002D HYPHEN-MINUS（`-`）开头的名称已被保留；请求这类名称会导致异常。
- [ ] 持有独占锁只能阻止同样通过 `navigator.locks.request()` 的其他调用方——它无法阻止未经请求锁而直接访问资源的代码。
- [ ] 使用 `ifAvailable` 选项可以立即失败而不是排队等待，使用 `AbortSignal` 可以为等待过久的请求设置超时。

## 下一步

- [Storage Buckets API](/zh/reference/capabilities/storage-buckets/)
- [Idle Detection API](/zh/reference/capabilities/idle-detection/)