Filas de tarefas em TypeScript: criação e otimização do processamento

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
Here is the translated HTML content in Portuguese, keeping all HTML tags and only translating the text content inside tags. ```html

Trabalhando com filas de tarefas em TypeScript: guia completo

No desenvolvimento web moderno e em aplicações de servidor, surge frequentemente a necessidade de executar tarefas de forma assíncrona, em segundo plano ou com limitação de paralelismo. As filas de tarefas (task queues) são um padrão poderoso que permite organizar a execução previsível e eficiente de operações. Neste artigo, vamos detalhar como criar e usar filas de tarefas em TypeScript, desde implementações simples até técnicas avançadas com prioridades e tratamento de erros.



O que é uma fila de tarefas e para que serve?

Uma fila de tarefas é uma estrutura de dados que funciona pelo princípio FIFO (First In, First Out). As tarefas são adicionadas ao final da fila e retiradas do início. No contexto do TypeScript e Node.js, as filas são usadas para:

  • Limitação de paralelismo — controle do número de operações executadas simultaneamente (por exemplo, requisições a APIs com limites).
  • Processamento assíncrono — execução de tarefas pesadas em segundo plano sem bloquear a thread principal.
  • Tentativas repetidas — reinicialização automática de tarefas que falharam com atraso.
  • Gerenciamento de ordem — garantia de execução sequencial de operações dependentes.

TypeScript adiciona tipagem estrita, tornando o código das filas mais confiável e previsível.



Implementação básica de uma fila de tarefas em TypeScript

Vamos começar criando uma fila simples, mas totalmente tipada. Ela aceitará tarefas (funções que retornam Promise) e as executará sequencialmente.

// Definindo o tipo de tarefatype Task<T> = () => Promise<T>;

// Classe da filaclass TaskQueue<T> { private queue: Task<T>[] = []; private isProcessing: boolean = false;

// Adicionando tarefa à fila enqueue(task: Task<T>): void { this.queue.push(task); this.process(); }

// Iniciando o processamento 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('Tarefa concluída:', result); } catch (error) { console.error('Erro ao executar tarefa:', error); } }

this.isProcessing = false; }}

// Exemplo de usoconst queue = new TaskQueue<string>();queue.enqueue(async () => { await new Promise(resolve => setTimeout(resolve, 1000)); return 'Primeira tarefa';});queue.enqueue(async () => 'Segunda tarefa (rápida)');

Esta implementação garante execução sequencial e início automático do processamento ao adicionar uma nova tarefa. No entanto, ela não suporta paralelismo nem prioridades.



Fila com limitação de paralelismo

Frequentemente, é necessário executar várias tarefas simultaneamente, mas sem exceder um certo limite (por exemplo, 5 requisições paralelas). Vamos adicionar o parâmetro 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('Sucesso:', result)) .catch(error => console.error('Erro:', error)) .finally(( ```

Blogs

Book Recommendations