Web Locks API:协调独占与共享工作
发布于 更新于
一句话: Web Locks API 的 navigator.locks.request() 方法异步请求一个命名锁,在持有该锁期间运行回调,并在回调结束后释放锁,让不同标签页或 worker 中的脚本协调对共享资源的访问。
await navigator.locks.request('my_resource', async (lock) => { // 同一时刻只有一个持有者能获得名为 'my_resource' 的独占锁。 await doWork();});独占锁与共享锁
Section titled “独占锁与共享锁”根据规范,请求锁时默认 mode: 'exclusive':当一个独占锁被持有时,同名的其他锁请求不会被授予。shared 锁则不同——多个针对同一名称的 shared 请求可以同时被授予,而针对该名称的 exclusive 请求仍需等待:
await navigator.locks.request('my_resource', { mode: 'shared' }, async () => { await readSharedData();});独占锁只能阻止另一个同样通过该 API 协作的调用方获取同名锁——它无法阻止绕过 navigator.locks 的代码直接读写底层资源。
作用域:共享存储桶的代理
Section titled “作用域:共享存储桶的代理”MDN 将锁描述为协调同源的标签页和 worker。规范的表述更精确:协作式协调发生在共享同一存储桶(storage bucket)的一组代理之间,这可能跨越多个代理集群(agent cluster)。因此,最终落在不同存储分区或存储桶中的上下文,即使同源,也不保证共享同一个锁管理器。
浏览器与生态支持
Section titled “浏览器与生态支持”- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop) | 支持 | 69 | 高 | 来源 | — |
| Chrome (Android) | 支持 | 69 | 高 | 来源 | 1 |
| Edge (Desktop) | 支持 | 79 | 高 | 来源 | 2 |
| Firefox (Desktop) | 支持 | 96 | 高 | 来源 | — |
| Firefox (Android) | 支持 | 96 | 高 | 来源 | 3 |
| Safari (macOS) | 支持 | 15.4 | 高 | 来源 | — |
| Safari (iOS) | 支持 | 15.4 | 高 | 来源 | 4 |
| Samsung Internet | 支持 | 10.0 | 高 | 来源 | 5 |
| WebView (Android) | 支持 | 69 | 高 | 来源 | 6 |
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 由 browser-compat-data 镜像自 Firefox 的数据推导。
- 由 browser-compat-data 镜像自 Safari 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
运行时检测与降级
Section titled “运行时检测与降级”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可以为等待过久的请求设置超时。