- 作者:老汪软件技巧
- 发表时间:2024-09-04 17:13
- 浏览量:
在逛MDN文档的时候瞄了一眼Lock板块,惊奇的发现,咱竟然也有“锁”的概念?抱着好奇心,我去研究了一波其用法,和应用场景,接下来众客官听我细细道来。
在此之前先放个文档LOCK。
如果懒得查看文档就看我一步步解析吧!
执行机制
本质上是一种用于在应用程序中管理资源同步的机制。它允许我们异步地获取、持有和释放对特定资源的锁,以确保在同一网页源中的不同上下文(如窗口、不同线程等)能有序地访问共享资源,从而避免潜在的数据竞争和冲突。
注意,上文的异步是指在待锁的过程中可以继续执行其他任务,倘若锁被成功获取,则进行相关资源操作;否则,将进入等待状态,直到锁可用。
以上的种种机制既保证了资源使用的安全性,又避免了阻塞问题。
代码示例
常用的API解析
一个简单的例子:
async function do_read() {
await navigator.locks.request(
"my_resource",
{ mode: "shared" },
async (lock) => {
// 执行锁后的逻辑操作
},
);
}
结合web-worker + indexDB实现数据独占锁
// lock.html
<script>
// 初始化 IndexedDB
function initDB(dbName) {
const request = indexedDB.open(dbName, 1);
request.onerror = (event) => {
console.error('error: ' + event.target.errorCode);
};
request.onsuccess = (event) => {
console.log('初始化成功!');
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
db.createObjectStore('items', { keyPath: 'id', autoIncrement: true });
};
}
// 创建并启动 Web Workers
function startWorkers(workerUrl, count) {
for (let i = 0; i < count; i++) {
const worker = new Worker(workerUrl);
worker.postMessage({ dbName: 'myDatabase' });
}
}
initDB('myDatabase');
startWorkers('js/worker.js', 2); // 启动两个 Worker
script>
上面代码:初始化indexDB,并开启两个worker线程,模拟数据竞争。
// js/worker.js
self.onmessage = function (e) {
const dbName = e.data.dbName
const lockName = dbName + '-lock'
function updateDatabase() {
try {
// 请求独占锁
navigator.locks.request(lockName, { mode: 'exclusive' }, lock => {
console.log(lock)
// 在锁的保护下访问数据库
const request = indexedDB.open(dbName, 1)
request.onerror = function (event) {
console.error("worker线程中读取indexDB失败:", event.target.errorCode)
}
request.onsuccess = function (event) {
const db = event.target.result
const tx = db.transaction('items', 'readwrite')
const store = tx.objectStore('items')
// 假设我们添加一条新数据
const item = { name: 'Item ' + Math.random() }
store.add(item)
tx.oncomplete = function () {
console.log('添加成功', lock.name)
}
tx.onerror = function (event) {
console.error('error:', event.target.errorCode)
}
}
})
} catch (error) {
console.error('error lock:', error)
}
}
updateDatabase()
}
利用锁的特性,加以保护IndexedDB数据库的访问。
应用场景
多窗口实行数据锁,解决在这种内部多小窗口化中的数据竞争。
需要注意的是,由于Web Locks API目前主要在Chrome和基于Chromium的浏览器中有实验性支持,并且可能还未成为正式标准,因此其应用场景可能有限且基于实验性实现。