A simple queue
[ts playground](https://www.typescriptlang.org/play?#code/PQKhCgAIUgXALAlgZ0gYwDYENmpZAV2QFMATOAe0gEcDi7IcBPAOzThwGtkA6KEYOGIAPAA4UATrHTZckAILJWaAIp0GAbyiRRBAEYZE7CcSykKLDExrriALkgAKRwEpIAXgB8kAAoSKALYoxAA8AG4UiKSeLgDaALoekAkA3ODaoBCQ2TC6yPCMHMiclHDwxDb0xDyQAJIAZmUVtFWQ+MQBorBMADRNRSUA7ogYGJB6FSLEaASwZG0BAWSIWHNWfNnQgtl58I6wXA6uHt5+gcHhkdEuDhFRkFqbZSg8LXQ8u-tcLmlPiI37JC8N7VDDEFgAcwQHnc7kgAEY3I8ns9eBICCxXL9NgBfbR4jJgbTQSAmGYSZCIMLEKykjH9A7FPAsfogjY5SAAZVgFFEkEG5RZCGatjaqA6XSY7K22lEEipqwqzDYdMxN18-iCJEuUW8yOyaAsyGkjJKcIQLxBsQADPFsdl-k4AISmtwmWAECQse1wCTWfWbLCDLCIE1cLHEyA49CrNAFRzECT+CRIyMGo0UME8RPJxwAAwAoknJJApjNYIhIQMHAASDQ5yQ4vM-SPR+qVrCjf1p1GvWw8fL-WARp54p5BkMmoE8dFq7F4gmGljGyoMOEsYiDBRKNhqKoR8BLlem+FJZXsY5eB7aCehyAbrdnLXEZwmZCZ6luK8Bo+Z0EUCFHAAIgAFS4BFIGNLApDIICWyeEhYBAxAlgoWZHDfD9iD6AAma18PgqMXB4YVMUvPVI1-LMMAA4CwOKCDDU6ME5lIOD5xbHE0kPI0w2KHCzx3C8vwo7Jb2kB8NXObU7miV9iHfDBqT6EwACtplgETryeKj-0A0DwIEqCYLYwjskQ5DUPQ8jtJRNSNMcSSi1zAyGIE8FDQxOYTHILAWQbCQ4LMqM+nhfDrUInFiNI5wtJ-DNqNo1ySgEgBhQJRBY2DIs47ijz4zgAGZBOUJw4pvYM70kp8Llkzx5MUz8Tls9Nlz-HgaP0+iSmK4zWPYyMLJQ4g0OHGyA2yTClJfYKcT6QrwpykjBVi5r4raxKuvA4qmMy4h+pytIuPSNlPhPFtTqIPZTRwi7+zOrhCpbIA)
```ts
/**
* this class is used to queue async tasks.
*/
export class AsyncQueue {
public readonly queue: (() => Promise<void>)[] = [];
/**
* push a task to the queue. If the queue is empty, the task will be executed immediately.
*/
push(task: () => Promise<void>): void {
this.queue.push(task);
if (this.queue.length === 1) {
this.run();
}
}
/**
* recursively run the tasks in the queue.
* Stop when the queue is empty.
*/
private async run(): Promise<void> {
const task = this.queue[0];
if (!task) return;
try {
await task();
} catch (error) {
console.error(`Error executing task: ${error}`);
} finally {
this.queue.shift();
}
await this.run();
}
}
const queue = new AsyncQueue();
const task1 = async () => {
await new Promise((resolve) => {
console.log("Task 1 started");
setTimeout(resolve, 2000);
}).then(() => {
console.log("Task 1 completed");
});
};
const task2 = async () => {
await new Promise<void>((resolve, reject) => {
console.log("Task 2 started");
setTimeout(() => {
reject(new Error("Task 2 encountered an error"));
}, 1000);
}).then(() => {
console.log("Task 2 Completed");
});
};
const task3 = async () => {
await new Promise<void>((resolve) => {
console.log("Task 3 started");
setTimeout(() => {
resolve();
}, 3000);
}).then(() => {
console.log("Task 3 completed");
});
};
queue.push(task1);
queue.push(task2);
queue.push(task3);
```