42 lines
1.1 KiB
TypeScript
42 lines
1.1 KiB
TypeScript
![]() |
export class RequestQueue<T> {
|
||
|
private pendingPromise = false;
|
||
|
private items: Array<{
|
||
|
action: (prevPayload?: T | null) => Promise<T>;
|
||
|
resolve: (value: T) => void;
|
||
|
reject: (reason?: any) => void;
|
||
|
}> = [];
|
||
|
|
||
|
enqueue(action: (prevPayload?: T | null) => Promise<T>) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
if (this.items.length === 2) {
|
||
|
this.items[1] = { action, resolve, reject };
|
||
|
} else {
|
||
|
this.items.push({ action, resolve, reject });
|
||
|
}
|
||
|
this.dequeue();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
async dequeue(prevPayload?: T | null) {
|
||
|
if (this.pendingPromise) return;
|
||
|
|
||
|
const item = this.items.shift();
|
||
|
if (!item) return;
|
||
|
|
||
|
let payload: T | null = null;
|
||
|
|
||
|
try {
|
||
|
this.pendingPromise = true;
|
||
|
payload = await item.action(prevPayload);
|
||
|
this.pendingPromise = false;
|
||
|
|
||
|
item.resolve(payload);
|
||
|
} catch (e) {
|
||
|
this.pendingPromise = false;
|
||
|
item.reject(e);
|
||
|
} finally {
|
||
|
this.dequeue(payload);
|
||
|
}
|
||
|
}
|
||
|
}
|