Created
October 28, 2022 12:52
-
-
Save lgrahl/75c64bb7da8f9b25599357b20f30f8b4 to your computer and use it in GitHub Desktop.
TS/JS Async Lock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A TypeScript async lock implemented with promise chaining. | |
* | |
* Usage: | |
* | |
* this._lock.with(async () => { | |
* await doThing1(); | |
* await doThing2(a); | |
* }); | |
*/ | |
export class AsyncLock { | |
private _queue: Promise<unknown> = Promise.resolve(); | |
/** | |
* Run an async function (the `executor`) within the scope of this lock. | |
* | |
* All enqueued executors are processed serially. | |
*/ | |
public with<T>(executor: () => T | Promise<T>): Promise<T> { | |
this._queue = this._enqueue(this._queue, executor); | |
return this._queue as Promise<T>; | |
} | |
/** | |
* Await the queue, then await and return the executor. | |
*/ | |
private async _enqueue<T>(queue: Promise<unknown>, executor: () => T | Promise<T>): Promise<T> { | |
try { | |
await queue; | |
} catch { | |
// Ignored | |
} | |
return await executor(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment