Einführung in Aufgabenwarteschlangen in TypeScript
\n\nEine Aufgabenwarteschlange (task queue) ist eine der grundlegenden Datenstrukturen in der Programmierung, die nach dem Prinzip "Wer zuerst kommt, mahlt zuerst" (FIFO) funktioniert. In TypeScript werden Aufgabenwarteschlangen häufig zur Verwaltung asynchroner Operationen, zur Verarbeitung von Anfragen, zur Organisation von Hintergrundprozessen und vielen anderen Szenarien eingesetzt.
\n\nIn diesem Artikel werden wir uns ansehen, wie man Aufgabenwarteschlangen in TypeScript von Grund auf erstellt und verwendet. Sie erfahren, wie Sie eine grundlegende Warteschlange implementieren, Prioritäten hinzufügen und Fehler behandeln. Das Material richtet sich an Anfänger, die mit den Grundlagen von TypeScript vertraut sind.
\n\nWas ist eine Aufgabenwarteschlange und wozu dient sie?
\n\nEine Warteschlange ist eine geordnete Liste von Elementen, bei der das Hinzufügen neuer Elemente am Ende und das Entnehmen am Anfang erfolgt. Stellen Sie sich eine Warteschlange im Geschäft vor: Der erste Kunde wird zuerst bedient, neue Kunden stellen sich hinten an.
\n\nIn der Programmierung werden Aufgabenwarteschlangen verwendet für:
\n\n- \n
- Asynchrone Verarbeitung — Ausführung von Aufgaben im Hintergrund ohne Blockierung des Hauptthreads \n
- Lastmanagement — Begrenzung der Anzahl gleichzeitig ausgeführter Operationen \n
- Ereignisverarbeitung — sequentielle Verarbeitung eingehender Anfragen \n
- Aufgabenplanung — Ausführung von Aufgaben mit Verzögerung oder nach Zeitplan \n
Implementierung einer grundlegenden Aufgabenwarteschlange in TypeScript
\n\nErstellen der Warteschlangenklasse
\n\nBeginnen wir mit einer einfachen Implementierung einer Warteschlange in TypeScript. Wir erstellen eine Klasse TaskQueue, die grundlegende Operationen unterstützt:
// task-queue.ts\ntype Task<T> = () => Promise<T>;\n\nclass TaskQueue<T> {\n private queue: Task<T>[] = [];\n private isProcessing = false;\n\n // Hinzufügen einer Aufgabe zur Warteschlange\n enqueue(task: Task<T>): void {\n this.queue.push(task);\n if (!this.isProcessing) {\n this.processQueue();\n }\n }\n\n // Verarbeitung der Warteschlange\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('Aufgabe ausgeführt:', result);\n } catch (error) {\n console.error('Fehler bei der Ausführung der Aufgabe:', error);\n }\n }\n\n this.isProcessing = false;\n }\n\n // Prüfen, ob die Warteschlange leer ist\n isEmpty(): boolean {\n return this.queue.length === 0;\n }\n\n // Größe der Warteschlange abrufen\n size(): number {\n return this.queue.length;\n }\n}\n\nVerwendung der Warteschlange
\n\nSehen wir uns nun an, wie wir unsere Klasse in der Praxis verwenden:
\n\n// example.ts\nconst taskQueue = new TaskQueue<string>();\n\n// Einige asynchrone Aufgaben erstellen\nconst task1 = async () => {\n await delay(1000);\n return 'Erste Aufgabe ausgeführt';\n};\n\nconst task2 = async () => {\n await delay(500);\n return 'Zweite Aufgabe ausgeführt';\n};\n\nconst task3 = async () => {\n await delay(200);\n return 'Dritte Aufgabe ausgeführt';\n};\n\n// Aufgaben zur Warteschlange hinzufügen\ntaskQueue.enqueue(task1);\ntaskQueue.enqueue(task2);\ntaskQueue.enqueue(task3);\n\n// Hilfsfunktion\nfunction delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// Ergebnis:\n// Aufgabe ausgeführt: Erste Aufgabe ausgeführt (nach 1s)\n// Aufgabe ausgeführt: Zweite Aufgabe ausgeführt (nach 1.5s)\n// Aufgabe ausgeführt: Dritte Aufgabe ausgeführt (nach 1.7s)\n\nErweiterte Warteschlange mit Prioritäten
\n\nIn realen Projekten müssen oft Aufgaben mit unterschiedlicher Priorität verarbeitet werden. Erweitern wir unsere Warteschlange um die Unterstützung von Prioritäten:
\n\n// priorit