npm 包 await-lock 使用教程

阅读时长 6 分钟读完

在前端开发中我们经常会遇到多个异步任务并发执行的情况,而且有些时候这些任务之间还需要互相配合,如同步某个共享资源。为了解决这类问题,ES2015 推出了 Promise 来处理异步操作,但有些时候我们也需要控制这些异步任务的执行,避免出现竞争条件,这时候可以使用 await-lock npm 包。

本篇文章主要介绍 await-lock 包的使用,帮助你了解如何用 await-lock 保证多个异步任务的按序执行。

什么是 await-lock?

await-lock 是一个 npm 包,提供了锁操作的支持,可以让异步任务等待锁在获取。它的实现类似于 Java 中的 synchronized,可以防止出现竞争条件。

如何使用 await-lock?

安装

安装 await-lock 当然可以使用 npm,打开命令行窗口,输入以下命令:

然后在你的代码中引入 await-lock

锁示例

实现基本的锁,可以使用以下代码:

我们通过 new AwaitLock() 创建了一个锁实例,并在 someFunction() 异步方法中使用了 lock.acquireAsync() 获取锁,在后面的同步代码执行前,所有尝试获取锁的异步方法都会被阻塞。同样的,我们可以使用 lock.release() 释放锁,让其他阻塞的异步方法继续执行。

读写锁示例

锁有两种常见类型,一种是互斥锁,它只允许有一个执行上下文进入临界区,另一种是读写锁,它可以支持多个读上下文同时进入临界区,但同时只能有一个写上下文在执行。

那么使用 await-lock 如何实现读写锁呢?

我们先来实现一个只支持共享资源互斥访问的锁,如下:

-- -------------------- ---- -------
------ - --------- - ---- -------------
----- ---- - --- ------------

----- ------------- -
  ------------- -
    -------- - --
  -

  ----- ------- -
    ----- --------------------
    -----------
    ---------------
  -

  ----- ------- -
    ----- --------------------
    ----------------------
    ---------------
  -
-

----- -------- - --- ----------------
--- ---- - - -- - - --- ---- -
  -----------------
-
----------------- -- -- --

为了避免竞争条件,我们对 incre()print() 方法分别使用了同一个锁保护对 this.val 的访问。如果一个线程在执行 incre(),其它线程的 incre()print() 方法都会被阻塞,直到当前线程执行完 release()

接下来,我们实现一个读写锁,这个锁支持多个线程同时读取共享资源,但同时只能有一个线程写入。

-- -------------------- ---- -------
------ - --------- - ---- -------------
----- ---- - --- ------------

----- ------------- -
  ------------- -
    -------- - --
    ------------- - --- ------------
    -------------- - --- ------------
    ------------ - --
  -

  ----- ------- -
    ----- ------------------------------
    -----------
    -------------------------
  -

  ----- ------- -
    ----- -----------------------------
    ---------------
    -- ------------- --- -- -
      ----- ------------------------------
    -
    ------------------------

    ----------------------

    ----- -----------------------------
    ---------------
    -- ------------- --- -- -
      -------------------------
    -
    ------------------------
  -
-

----- -------- - --- ----------------
--- ---- - - -- - - --- ---- -
  ------------- -- - ----------------- -- ------------- - ------
-
--- ---- - - -- - - --- ---- -
  ------------- -- - ----------------- -- ------------- - ------
-

我们在类中添加了两个锁分别用来保护读和写,还新增了一个计数值 readers,用来记录当前有多少线程正在读取。

在访问 val 的时候,我们首先获取了 readLock 进入读取阶段。如果当前没有其它线程正在读取,那么我们就获取 writeLock 进入写入阶段。所有访问 val 的线程都需要获得 readLock,一旦访问完成后必须释放锁,以便其它线程访问。当没有线程在读取时,写入线程可以获得 writeLock,然后更新共享资源,并且释放掉 writeLock

总结

本文介绍了 await-lock 包的使用,它提供了一个简单的锁机制,能够保证同一时间只有一个执行上下文进入关键区域执行,从而避免了竞争条件的产生。而且,我们还介绍了如何使用 await-lock 实现读写锁,并提供了代码示例来帮助读者更好的了解如何使用。

希望这篇文章对你有所帮助!

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/70250

纠错
反馈