注册
web

前端可以玩“锁”🔐了

大家好,我是CC,在这里欢迎大家的到来~


“锁”经常使用在多进程的语言理和数据库事务的架构当中,现在 Web API 当中也提供了“锁”- Web Locks API


领域


在浏览器多标签页或 worker 中运行的脚本中获取锁,执行工作时保持锁,最后释放锁。



锁的范围仅限于同一源内



请求锁


同一源下,当持有锁时,其他相同锁的请求将排队,仅当锁被释放时第一个排队的请求才会被授予锁。



回调函数执行完毕后锁会自动释放



navigator.locks.request('mylock', {}, async (lock) => {
console.log(lock);
});

在这里我们能看到 request 方法的第二个参数(可选),可以在请求锁时传递一些选项,这个我们在后边会介绍到。


监控锁


判断锁管理器的状态,有利于调试;返回结果是一个锁管理器状态的快照,标识了持有锁和请求中的锁的有关数据,像名称、client_id和模式。


navigator.locks.query().then((locks) => {
console.log(locks);
});

实现


接下来将使用请求锁的可选参数实现以下内容:


从异步任务返回值


request() 方法本身返回一个 Promise,一旦锁被释放,该 Promise 就会 resolve。


const result = await navigator.locks.request('ccmama'}, async (lock) => {
// 任务
return data;
});
// 拿到内部回调函数返回的 data
console.log(result);

共享锁和独占锁模式


配置项 mode 默认是 'exclusive',可选项还有 'shared'。



锁只能有一个持有者,但是可以同时授权多个共享。


在读写模式中经常使用 'shared' 模式进行读取,'exclusive' 模式用于写入。



navigator.locks.request('ccmama', {
mode: 'shared',
}, async (lock) => {
// 任务
});


📢


持有 'exclusive' 锁,同名 'exclusive' 锁排队等候


持有 'exclusive' 锁,同名 'shared' 锁排队等候


持有 'shared' 锁,同名 'shared' 锁也可访问同一资源


持有 'shared' 锁,同名 'exclusive' 锁排队等候



条件获取


配置项 ifAvailable 默认 false,当设置 true 时锁请求仅在不需要排队时才会被授予,也就是说在任务没有其他等待的情况下锁请求才会被授予,否则返回 null。


navigator.locks.request('ccmama', { ifAvailable: true }, async lock => {
if (!lock) return;
// 任务
});


注意:同名锁



防止死锁的应急通道


配置项 steal 默认 false,当设置为 true 时任何持有的同名锁将被释放,并且请求将被授权,抢占任何排队中的锁请求。


navigator.locks.request('ccmama', { steal: true }, async lock => {
// 任务
});


⚠️


使用要小心。之前在锁内运行的代码会继续运行,并且可能与现在持有锁的代码发生冲突。



中止锁定请求


配置项 signal 是 AbortSignal 类型;如果指定并且 AbortController 被中止,则锁请求将被丢弃。


try {
const controller = new AbortController();
setTimeout(() => controller.abort(), 400);
navigator.locks.request('ccmama', { signal: controller.signal }, async lock => {
// 任务
});
} catch(ex) {}

// 或

try {
navigator.locks.request('ccmama', { signal: AbortSignal.timeout(1000) }, async lock => {
// 任务
});
} catch(ex) {}


⚠️


超时时会报出一个异常错误,需要使用 try catch 捕获



参考文章



可能理解并不一定到位,欢迎交流。


作者:CC码码
来源:juejin.cn/post/7382640456109490211

0 个评论

要回复文章请先登录注册