Skip to content

Web Locks API 使用文档(译) #88

@aermin

Description

@aermin

原始MDN链接

实验
这是一项实验性技术,请在生产中使用它之前仔细检查浏览器兼容性表。

Web Locks API允许运行在一个选项卡或工作程序中的脚本去异步获取锁,在执行工作时将其保留,然后释放它。在保持状态的同时,其他在同一源执行的脚本都无法获得相同的锁,这使得在多个选项卡或工作程序中运行的Web应用程序可以协调工作和资源的使用。

Web Locks 的概念和用法

锁是代表一些潜在共享资源的抽象概念,它由Web应用程序选择的名称标识。例如,如果运行在多个选项卡中的Web应用程序要确保只有一个选项卡在网络和索引数据库之间同步数据,则每个选项卡都可以尝试获取"my_net_db_sync"锁,但只有一个选项卡会成功(领导者选举模式

该API的用法如下:

  1. 请求该锁。
  2. 在持锁时的异步任务中将工作完成。
  3. 当任务完成时,该锁将自动释放。
navigator.locks.request('my_resource', async lock => {
  // The lock has been acquired.
  await do_something();
  await do_something_else();
  // Now the lock will be released.
});

持有锁时,将从此执行上下文或其他选项卡/工作器中请求相同锁的请求排队。仅当释放锁定时,才会批准第一个排队的请求。

该API提供了可根据需要使用的可选功能,包括:

  • 从异步任务返回值
  • 共享和独占锁定模式
  • 有条件获取
  • 诊断以查询源中的锁状态
  • 可防止死锁的逃生舱口

锁的作用域是origins;选项卡从https://example.com获得的锁对标签来自https://example.org:8080的锁没有影响,因为它们是不同的origins。

主要入口点是navigator.locks.request(),它请求锁定。它需要一个锁名,一组可选的选项以及一个回调。授予锁定时将调用回调。当回调返回时,锁会自动释放,因此通常回调是​​一个异步函数,这导致仅在异步函数完全完成后才释放锁。

request() 方法本身返回一个promise,一旦释放锁,该promise就会解析。在异步函数中,脚本可以await调用从而使异步代码流能线性化。例如:

await do_something_without_lock();

// Request the lock.
await navigator.locks.request('my_resource', async lock => {
  // The lock has been acquired.
  await do_something_with_lock();
  await do_something_else_with_lock();
  // Now the lock will be released.
});
// The lock has been released.

await do_something_else_without_lock();

Options参数

请求锁定时可以传递几个选项:

  • mode:默认mode为"exclusive"("独占"),但可以指定"shared"("共享")。锁只能有一个"exclusive",但是可以同时授予多个"shared"请求。这可以用来实现读者-作家模式

  • signal: 可以传递AbortSignal,从而允许中止锁定请求。这可用于对请求实施超时。

  • ifAvailable: 如果指定,且在锁不能马上被授予的情况下(没有等待),lock request将失败。The callback is invoked with null.

Monitoring监控方式

脚本可以使用navigator.locks.query()方法对源的锁管理器的状态进行内省。这在调试时很有用,例如,确定为什么无法获取锁。结果是锁管理器状态的快照,该快照标识保留快照和请求的锁,以及在获取快照时有关每个锁的一些其他数据(例如模式)。

Advanced use高级使用

对于更复杂的情况,例如在任意时间保持锁,回调可以返回由脚本显式解决的promise:

// Capture promise control functions:
let resolve, reject;
const p = new Promise((res, rej) => { resolve = res; reject = rej; });

// Request the lock:
navigator.locks.request('my_resource', lock => {
  // Lock is acquired.

  return p;
  // Now lock will be held until either resolve() or reject() is called.
});

Deadlocks死锁

当进程由于每个部分都在等待无法满足的请求而无法继续进行时,将发生死锁。使用此API可能会在复杂的用例中发生这种情况,例如,如果无序请求多个锁。如果选项卡1持有锁A,而选项卡2持有锁B,则选项卡1尝试也获得锁B,而选项卡2尝试也获得锁A,则均不能授予任何请求。 Web应用程序可以通过几种策略来避免这种情况,例如确保锁定请求不嵌套,始终保持良好的顺序或超时。请注意,此类死锁只会影响锁本身,并取决于锁而影响代码;页面中的浏览器,其他选项卡和其他脚本不受影响。

Interfaces 接口

Lock

提供先前请求的锁的name 和 mode,该锁在锁管理器LockManager.request()的回调中接收。

LockManager

提供用于请求新的Lock对象和查询现有Lock对象的方法。要获取LockManager的实例,请调用navigator.locks。

Browser compatibility 浏览器支持

LockManager

在 GitHub 上报告此兼容性数据的问题

image

Lock

在 GitHub 上报告此兼容性数据的问题

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions