Skip to content

Instantly share code, notes, and snippets.

@Darmikon
Last active July 8, 2020 21:27
Show Gist options
  • Save Darmikon/5334cebbe7ec325ab2d5bb4634c8babb to your computer and use it in GitHub Desktop.
Save Darmikon/5334cebbe7ec325ab2d5bb4634c8babb to your computer and use it in GitHub Desktop.
async-queue.ts demo
type TCallback = (arg0?: any) => Promise<any>;
class AsyncQueue {
private queue: (() => void)[] = [];
private inProgress: boolean = false;
private intervalId: Timeout;
private interval: number = 1000;
private start() {
this.intervalId = setInterval(() => this.next(), this.interval);
};
private stop() {
clearInterval(this.intervalId);
};
private next() {
// if some request is still pending
if (this.inProgress) return;
// if the queue is empty
if (!this.queue.length) {
this.stop();
return;
}
const [first, ...rest]: TCallback[] = this.queue;
this.queue = rest || [];
// disable any new request until the current is completed
this.inProgress = true;
first();
};
wrap(wrapped: TCallback) {
return (...rest: any[]) => new Promise((resolve, reject) => {
this.queue.push(() => {
wrapped(...rest)
.then(resolve, reject)
.finally(() => {
// unlock ability to run the next callback in the queue
this.inProgress = false;
});
});
if (!this.intervalId) {
// activate polling if not active
this.start();
}
});
};
}
const asyncQueue = new AsyncQueue();
export const asyncFoo1 = asyncQueue.wrap(ASYNC_CALLBACK_1);
export const asyncFoo2 = asyncQueue.wrap(ASYNC_CALLBACK_2);
export const asyncFoo3 = asyncQueue.wrap(ASYNC_CALLBACK_3);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment