export default class AsyncQueue { private _queue: T[]; private canGet: Promise; private resolveGet: (value: boolean) => void; private canPush: Promise | boolean; private resolvePush: (value: boolean) => void; constructor() { this._queue = []; this.resolvePush = () => {}; this.resolveGet = () => {}; this.canGet = new Promise((resolve) => { this.resolveGet = resolve; }); this.canPush = true; } async push(value: T) { await this.canPush; this._queue.push(value); this.resolveGet(true); this.canPush = new Promise((resolve) => { this.resolvePush = resolve; }); } async pop() { await this.canGet; const returned = this._queue.pop(); this.resolvePush(true); this.canGet = new Promise((resolve) => { this.resolveGet = resolve; }); return returned; } }