From eee00e42f34417f34f8e2bbb4d4b155b4a5f3586 Mon Sep 17 00:00:00 2001 From: ido Date: Thu, 22 Feb 2024 14:40:10 +0200 Subject: [PATCH] feat: `withLock` support `this` scope --- README.md | 6 +++--- src/withLock.ts | 14 +++++++------- test/withLock.test.ts | 12 ++++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1c8cac4..b617ce8 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,13 @@ Calling `withLock` with the same `scope` and `key` will ensure that the callback ```typescript import {withLock} from "lifecycle-utils"; -const scope = {}; // can be a reference to any object you like +const scope = {name: 'Tommy'}; // can be a reference to any object you like const startTime = Date.now(); async function doSomething(index: number): number { - return await withLock(scope, "myKey", async () => { + return await withLock(scope, "myKey", async function () { await new Promise(resolve => setTimeout(resolve, 1000)); - console.log("index:", index, "time:", Date.now() - startTime); + console.log("index:", index, "time:", Date.now() - startTime, "name:", this.name); return 42; }); } diff --git a/src/withLock.ts b/src/withLock.ts index 53339f1..18af81b 100644 --- a/src/withLock.ts +++ b/src/withLock.ts @@ -3,14 +3,14 @@ const locks = new Map>>(); /** * Only allow one instance of the callback to run at a time for a given `scope` and `key`. */ -export async function withLock(scope: any, key: string, callback: () => Promise): Promise; -export async function withLock( - scope: any, key: string, acquireLockSignal: AbortSignal | undefined, callback: () => Promise +export async function withLock(scope: ScopeType, key: string, callback: (this: ScopeType) => Promise): Promise; +export async function withLock( + scope: ScopeType, key: string, acquireLockSignal: AbortSignal | undefined, callback: (this: ScopeType) => Promise ): Promise; -export async function withLock( - scope: any, +export async function withLock( + scope: ScopeType, key: string, - acquireLockSignalOrCallback: AbortSignal | undefined | (() => Promise), + acquireLockSignalOrCallback: AbortSignal | undefined | ((this: ScopeType) => Promise), callback?: () => Promise ): Promise { let acquireLockSignal: AbortSignal | undefined = undefined; @@ -47,7 +47,7 @@ export async function withLock( throw acquireLockSignal.reason; } - const promise = callback(); + const promise = callback.call(scope); if (!locks.has(scope)) locks.set(scope, new Map()); diff --git a/test/withLock.test.ts b/test/withLock.test.ts index cf5f002..a41ded5 100644 --- a/test/withLock.test.ts +++ b/test/withLock.test.ts @@ -300,6 +300,18 @@ describe("withLock", () => { // do nothing } }); + + test("this scope works", async () => { + const scope = {data: 1}; + const key = "key"; + + let calls = 0; + await withLock(scope, key, async function (){ + expect(this).toBe(scope); + calls++; + }); + expect(calls).toBe(1); + }); });