Web Locks API 必须通过 JavaScript 的 navigator.locks.request() 调用,不支持 HTML 属性;需 await、回调返回 Promise、锁名绑定具体资源且 URL-safe;Safari 不支持;防覆盖须配合 IndexedDB 并 await tx.done。
Web Locks API 不能在 HTML 中直接使用——它没有 HTML 标签、属性或事件,必须通过 JavaScript 调用 navigator.locks.request() 才能生效。把锁逻辑写进 里是唯一可行方式,且需满足安全上下文(HTTPS 或 localhost)。
为什么不能在 HTML 标签里加 lock 属性或 data-lock
Web Locks API 是纯 JavaScript 接口,浏览器不解析任何 HTML 属性来触发锁行为。试图写 或
- 所有锁操作必须显式调用
navigator.locks.request(),且返回的是 Promise - 锁名(如
'user-cart-123')必须由 JS 动态生成并传入,不能硬编码在 HTML 结构中 - HTML 只负责承载触发锁的 UI 元素(比如按钮),真正的协调逻辑全部在 JS 里
navigator.locks.request() 必须 await,否则锁立即释放
常见错误是调用后不 await,导致锁在函数退出瞬间就释放,根本起不到互斥作用。尤其在事件处理器中极易踩坑:
button.addEventListener('click', () => {
// ❌ 错误:没 await,锁秒放
navigator.locks.request('cart-write', () => updateCart());
// ✅ 正确:必须 await,且回调要返回 Promise
navigator.locks.request('cart-write', async () => {
await updateCart(); // updateCart() 内部必须是异步操作
});
});
- 不
awaitnavigator.locks.request(),等于没加锁 - 回调函数必须返回 Promise(如
async () => {...}或显式return Promise.resolve()),否则锁在同步代码执行完后立刻释放 - 锁释放时机 = 回调返回 Promise 并 resolve/reject 后,不是函数开始执行时
锁名必须带业务标识,不能写死成 'lock'
用固定字符串如 'lock' 或 'data' 作锁名,会导致所有用户、所有资源共用同一把锁——A 用户编辑购物车时,B 用户连个人设置都保存不了。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
立即学习“前端免费学习笔记(深入)”;
- 正确做法:锁名绑定具体资源,例如
`cart-write-${userId}`、`prefs-${accountId}` - 锁名需 URL-safe:避免空格、斜杠、控制字符;可对用户输入做
encodeURIComponent()清理,但非必需 - 长度建议 ≤64 字符;过长(如 >256)可能影响内部哈希性能,且无实际语义增益
- Safari 完全不支持该 API(截至 iOS 17.5),仅靠
if ('locks' in navigator)判断跳过逻辑,等于放弃所有协调保障
真正串行化写入,必须搭配 IndexedDB 而非 localStorage
很多人以为给 localStorage.setItem() 加锁就能防覆盖,结果发现照样丢数据——因为 localStorage 是同步阻塞 API,锁根本插不进它的执行流。
-
localStorage.setItem()在调用瞬间就完成,navigator.locks.request()的异步机制无法干预 - 真正能串行化的方案是:用锁包裹「打开 IndexedDB → 读取 → 修改 →
put()→await tx.done」整段流程 - 必须
await tx.done,只调用tx.commit()不够——后者不保证写入落地,锁提前释放会导致其他标签页读到脏数据 - 若非得用
localStorage,只能做轻量提示(如存lock:cart-${id}+ 监听storage事件),但这不防止覆盖,仅用于弹窗提醒
最容易被忽略的是锁的语义边界:它只保证“最多一个标签页执行某段 JS”,不保证数据最终一致。你得自己确保那段 JS 真的完成了原子写入——比如漏了 await tx.done,或者把耗时计算塞进锁回调里,都会让锁形同虚设。
