Skip to content

Instantly share code, notes, and snippets.

@lgrahl
Created October 28, 2022 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lgrahl/75c64bb7da8f9b25599357b20f30f8b4 to your computer and use it in GitHub Desktop.
Save lgrahl/75c64bb7da8f9b25599357b20f30f8b4 to your computer and use it in GitHub Desktop.
TS/JS Async Lock
/**
* 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