export type Release = { release: () => void }; export default class Lock { private _locked: boolean = false; get locked() { return this._locked; } private toCome: (() => void)[] = []; constructor() { this.release = this.release.bind(this); } async getLock(): Promise { if (!this._locked) return { release: this.lock() }; else { return new Promise((resolve) => { this.toCome.push(() => { resolve({ release: this.lock() }); }) }) } } private lock() { this._locked = true; return this.release; } private async release() { if (this.toCome.length > 0) { this.toCome.shift()(); } else { this._locked = false; } } }