无需登录 数据私有 本地保存

Web Locks API演示 - 多标签页资源协调

41
0
0
0

Web Locks API 演示

API 就绪 活跃标签页: 1 等待中: 0
预设资源
📄
共享文档编辑
空闲
🖨️
打印机队列
空闲
💾
数据库写入
空闲
🔑
API 速率限制
空闲
锁操作面板
当前持有的锁
当前没有锁被持有
操作日志
暂无操作日志

常见问题与知识点

什么是 Web Locks API?它解决什么问题?
Web Locks API 是一种浏览器原生提供的分布式锁机制,允许同一源(origin)下的所有标签页、Worker 和 iframe 协调对共享资源的访问。它解决了多标签页并发操作时的竞态条件问题——比如两个标签页同时写入 localStorage、同时操作 IndexedDB 数据、或同时发起 API 请求导致速率限制被触发。锁在回调函数返回后自动释放,即使发生异常也不会造成死锁,极大简化了资源协调的复杂度。
独占锁(Exclusive)和共享锁(Shared)有什么区别?
独占锁:同一时间只有一个客户端可以持有,其他请求必须排队等待。适用于写入操作(如更新数据库记录、修改共享状态),确保数据一致性。

共享锁:多个客户端可以同时持有同一把共享锁,但当有独占锁请求在等待时,新的共享锁请求也会被阻塞。适用于读取操作,允许多个标签页并发读取,但写入时需要独占。这类似于数据库中的读写锁机制(Read-Write Lock),在保证数据一致性的同时最大化读取并发性能。
Web Locks API 的浏览器兼容性如何?
Web Locks API 在 Chrome 69+Edge 79+Firefox 96+Safari 15.4+ 以及 Opera 56+ 中得到支持。截至2024年,全球浏览器覆盖率超过93%。需要注意的是,该 API 仅在安全上下文(HTTPS 或 localhost)中可用。在不支持的浏览器中,可以考虑使用 IndexedDB 事务或基于 postMessage 的自定义锁方案作为降级策略。
锁超时如何处理?navigator.locks.request 的 signal 参数有什么用?
navigator.locks.request() 接受一个可选的 signal 参数(来自 AbortController)。当 signal 被 abort 时,如果锁请求仍在等待队列中,会立即抛出 AbortError 异常,请求被取消。这实现了超时机制——通过 setTimeout 触发 abort,避免请求无限期等待。

重要:signal 只能取消等待中的请求。如果锁已经被获取并正在回调中执行,abort signal 不会中断回调——锁会继续持有直到回调完成。如果需要可中断的持锁操作,应在回调内部自行处理中断逻辑。
navigator.locks.query() 能查询到什么信息?
navigator.locks.query() 返回一个 Promise,解析为包含两个数组的对象:
held:当前被持有的所有锁,每项包含 name(锁名称)、mode('exclusive' 或 'shared')、clientId(持有者标识)
pending:当前等待队列中的所有锁请求,结构同 held

这是一个只读快照,用于监控锁状态。在本演示工具中,我们每秒自动调用 query() 来刷新资源卡片的状态,让你实时看到多标签页之间的锁协调效果。
如何在多标签页之间检测和同步锁状态?
本演示工具使用了两种机制:
1. navigator.locks.query() 轮询:每秒查询一次全局锁状态,这是获取真实锁信息的权威来源。
2. BroadcastChannel API:在标签页之间广播操作事件(获取锁、释放锁、心跳),实现即时通知和标签页计数。

两者配合使用:BroadcastChannel 提供低延迟的事件通知,而 query() 轮询确保状态最终一致。你可以打开多个标签页访问本工具,观察它们如何通过 Web Locks API 协调对同一资源的访问。
Web Locks API 能否防止死锁?
Web Locks API 在设计上天然避免了一些死锁场景:锁在回调函数返回后自动释放,即使回调中抛出异常也不会导致锁被永久持有。此外,signal 超时机制可以防止请求无限等待。

然而,跨资源的循环依赖死锁(如标签页A持有锁1等待锁2,标签页B持有锁2等待锁1)仍可能发生。避免此类死锁的最佳实践是:始终以相同顺序请求多把锁,并设置合理的超时时间。浏览器目前不提供死锁检测机制。
Web Locks API 和 IndexedDB 事务、localStorage 操作有什么区别?
IndexedDB 事务:提供数据库级别的原子操作保护,但仅限于 IndexedDB 操作,无法协调其他资源(如 API 请求、DOM 操作)。
localStorage:没有任何内置锁机制,多标签页同时写入可能导致数据丢失或损坏。
Web Locks API:提供通用的、跨标签页的锁机制,可以保护任何 JavaScript 操作——无论是 localStorage 写入、API 调用、还是 DOM 更新。它是应用层的协调原语,比 IndexedDB 事务更灵活,比手动实现锁更可靠。