Introdução às Filas de Tarefas em TypeScript
Uma fila de tarefas (Queue) é uma das estruturas de dados fundamentais na programação, que funciona pelo princípio FIFO (First In, First Out — "o primeiro a entrar é o primeiro a sair"). Imagine uma fila comum em uma loja: o primeiro cliente que entra na fila é atendido primeiro. Na programação, a fila de tarefas é usada em toda parte: desde o processamento de requisições no servidor até o gerenciamento de operações assíncronas no navegador.
Neste artigo, vamos analisar como criar e usar uma fila de tarefas em TypeScript. Você aprenderá como tipificar a fila, implementar os métodos principais e aplicá-la em projetos reais. O material é voltado para desenvolvedores iniciantes familiarizados com os fundamentos do TypeScript.
Operações Básicas com a Fila
Qualquer fila de tarefas deve suportar algumas operações básicas:
- enqueue (adicionar um elemento ao final da fila);
- dequeue (remover um elemento do início da fila);
- peek (visualizar o primeiro elemento sem removê-lo);
- isEmpty (verificar se a fila está vazia);
- size (obter a quantidade de elementos).
Em TypeScript, podemos implementar uma fila baseada em array ou lista encadeada. Para simplificar, começaremos com o array.
Implementação da Fila Baseada em Array
Vamos criar uma classe Queue usando genéricos — isso permitirá armazenar dados de qualquer tipo:
class Queue<T> { private items: T[] = [];
// Adicionar um elemento ao final da fila enqueue(element: T): void { this.items.push(element); }
// Remover e retornar o primeiro elemento dequeue(): T | undefined { return this.items.shift(); }
// Visualizar o primeiro elemento sem removê-lo peek(): T | undefined { return this.items[0]; }
// Verificar se a fila está vazia isEmpty(): boolean { return this.items.length === 0; }
// Obter o tamanho da fila size(): number { return this.items.length; }}Agora podemos criar uma fila para qualquer tipo de dado:
// Fila de stringsconst stringQueue = new Queue<string>();stringQueue.enqueue('Tarefa 1');stringQueue.enqueue('Tarefa 2');console.log(stringQueue.dequeue()); // 'Tarefa 1'
// Fila de númerosconst numberQueue = new Queue<number>();numberQueue.enqueue(10);numberQueue.enqueue(20);console.log(numberQueue.peek()); // 10Desvantagens da Implementação com Array
O método shift() em JavaScript/TypeScript tem complexidade O(n), pois após remover o primeiro elemento, todos os outros são deslocados. Para grandes volumes de dados, isso é ineficiente. A solução é implementar uma fila baseada em objeto ou lista encadeada.
Fila Otimizada com Objeto
Para evitar o deslocamento de elementos, vamos armazenar os elementos em um objeto e rastrear os índices de início e fim:
class OptimizedQueue<T> { private items: Record<number, T> = {}; private head: number = 0; private tail: number = 0;
enqueue(element: T): void { this.items[this.tail] = element; this.tail++; }
dequeue(): T | undefined { if (this.isEmpty()) { return undefined; } const item = this.items[this.head]; delete this.items[this.head]; this.head++; return item; }
peek(): T | undefined { return this.items[this.head]; }
isEmpty(): boolean { return this.tail === this.head; }
size(): number { return this.tail - this.head; }}Agora as operações enqueue e dequeue são executadas em O(1) — tempo constante, independentemente