Files d'attente de tâches en TypeScript : création et optimisation du traitement

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Travailler avec les files d'attente de tâches en TypeScript : Un guide complet

Dans le développement web moderne et les applications serveur, il est souvent nécessaire d'exécuter des tâches de manière asynchrone, en arrière-plan, ou avec des limites de concurrence. Les files d'attente de tâches sont un modèle puissant qui permet d'organiser une exécution prévisible et efficace des opérations. Dans cet article, nous allons examiner en détail comment créer et utiliser des files d'attente de tâches en TypeScript, des implémentations simples aux techniques avancées avec priorités et gestion des erreurs.



Qu'est-ce qu'une file d'attente de tâches et pourquoi en a-t-on besoin ?

Une file d'attente de tâches est une structure de données fonctionnant sur le principe FIFO (First In, First Out). Les tâches sont ajoutées à la fin de la file et récupérées depuis le début. Dans le contexte de TypeScript et Node.js, les files d'attente sont utilisées pour :

  • Limitation de concurrence — contrôler le nombre d'opérations s'exécutant simultanément (par exemple, les requêtes API avec limites).
  • Traitement asynchrone — exécuter des tâches lourdes en arrière-plan sans bloquer le thread principal.
  • Nouvelles tentatives — redémarrage automatique des tâches échouées avec un délai.
  • Gestion de l'ordre — garantir l'exécution séquentielle des opérations dépendantes.

TypeScript ajoute un typage strict, rendant le code des files d'attente plus fiable et prévisible.



Implémentation de base d'une file d'attente de tâches en TypeScript

Commençons par créer une file simple mais entièrement typée. Elle acceptera des tâches (des fonctions retournant une Promise) et les exécutera séquentiellement.

// Define the task typetype Task<T> = () => Promise<T>;

// Queue classclass TaskQueue<T> { private queue: Task<T>[] = []; private isProcessing: boolean = false;

// Add task to queue enqueue(task: Task<T>): void { this.queue.push(task); this.process(); }

// Start processing private async process(): Promise<void> { if (this.isProcessing) return; this.isProcessing = true;

while (this.queue.length > 0) { const task = this.queue.shift()!; try { const result = await task(); console.log('Task completed:', result); } catch (error) { console.error('Task execution error:', error); } }

this.isProcessing = false; }}

// Usage exampleconst queue = new TaskQueue<string>();queue.enqueue(async () => { await new Promise(resolve => setTimeout(resolve, 1000)); return 'First task';});queue.enqueue(async () => 'Second task (fast)');

Cette implémentation garantit une exécution séquentielle et un démarrage automatique du traitement lorsqu'une nouvelle tâche est ajoutée. Cependant, elle ne prend pas en charge le parallélisme ni les priorités.



File d'attente avec limite de concurrence

Il est souvent nécessaire d'exécuter plusieurs tâches simultanément sans dépasser une certaine limite (par exemple, 5 requêtes parallèles). Ajoutons un paramètre concurrency.

class ParallelTaskQueue<T> {    private queue: Task<T>[] = [];    private activeCount: number = 0;    private readonly concurrency: number;

constructor(concurrency: number = 3) { this.concurrency = concurrency; }

enqueue(task: Task<T>): void { this.queue.push(task); this.processNext(); }

private processNext(): void { while (this.activeCount < this.concurrency && this.queue.length > 0) { const task = this.queue.shift()!; this.activeCount++; task() .then(result => console.log('Success:', result)) .catch(error => console.error('Error:', error)) .finally(

Blogs

Book Recommendations