Introduction to Task Queues in TypeScript
\n\nA task queue is one of the fundamental data structures in programming, operating on a "first in, first out" (FIFO) principle. In TypeScript, task queues are widely used for managing asynchronous operations, processing requests, organizing background processes, and many other scenarios.
\n\nIn this article, we will break down how to create and use task queues in TypeScript from scratch. You will learn how to implement a basic queue, add priorities, and handle errors. The material is aimed at beginner developers familiar with the basics of TypeScript.
\n\nWhat is a Task Queue and Why is it Needed?
\n\nA queue is an ordered list of elements where new elements are added to the end and removed from the beginning. Imagine a queue in a store: the first customer is served first, and new customers go to the end.
\n\nIn programming, task queues are used for:
\n\n- \n
- Asynchronous processing — executing tasks in the background without blocking the main thread \n
- Load management — limiting the number of simultaneously executing operations \n
- Event processing — sequential processing of incoming requests \n
- Task scheduling — executing tasks with a delay or on a schedule \n
Implementing a Basic Task Queue in TypeScript
\n\nCreating the Queue Class
\n\nLet's start with a simple queue implementation in TypeScript. We'll create a TaskQueue class that supports basic operations:
// task-queue.ts\ntype Task<T> = () => Promise<T>;\n\nclass TaskQueue<T> {\n private queue: Task<T>[] = [];\n private isProcessing = false;\n\n // Adding a task to the queue\n enqueue(task: Task<T>): void {\n this.queue.push(task);\n if (!this.isProcessing) {\n this.processQueue();\n }\n }\n\n // Processing the queue\n private async processQueue(): Promise<void> {\n this.isProcessing = true;\n\n while (this.queue.length > 0) {\n const task = this.queue.shift()!;\n try {\n const result = await task();\n console.log('Task completed:', result);\n } catch (error) {\n console.error('Error executing task:', error);\n }\n }\n\n this.isProcessing = false;\n }\n\n // Check if the queue is empty\n isEmpty(): boolean {\n return this.queue.length === 0;\n }\n\n // Get the queue size\n size(): number {\n return this.queue.length;\n }\n}\n\nUsing the Queue
\n\nNow let's see how to use our class in practice:
\n\n// example.ts\nconst taskQueue = new TaskQueue<string>();\n\n// Create several asynchronous tasks\nconst task1 = async () => {\n await delay(1000);\n return 'First task completed';\n};\n\nconst task2 = async () => {\n await delay(500);\n return 'Second task completed';\n};\n\nconst task3 = async () => {\n await delay(200);\n return 'Third task completed';\n};\n\n// Add tasks to the queue\ntaskQueue.enqueue(task1);\ntaskQueue.enqueue(task2);\ntaskQueue.enqueue(task3);\n\n// Helper function\nfunction delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// Result:\n// Task completed: First task completed (after 1s)\n// Task completed: Second task completed (after 1.5s)\n// Task completed: Third task completed (after 1.7s)\n\nAdvanced Queue with Priorities
\n\nIn real projects, it is often necessary to process tasks with different priorities. Let's extend our queue by adding priority support:
\n\n// priorit