Concorrência e Multithreading em TypeScript: Nível Avançado

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

Concorrência e Multithreading em TypeScript: Nível Avançado



No desenvolvimento web moderno e em aplicações servidoras em TypeScript, a capacidade de trabalhar eficientemente com concorrência e multithreading torna-se criticamente importante. Embora o JavaScript seja uma linguagem single-threaded, o ambiente de execução (navegador ou Node.js) fornece ferramentas poderosas para execução paralela de tarefas. Neste artigo, exploraremos técnicas avançadas de trabalho com concorrência em TypeScript, incluindo Worker Threads, SharedArrayBuffer, Atomics e padrões de sincronização.



1. Fundamentos: Event Loop e async/await



Antes de mergulhar no multithreading, é importante entender como o Event Loop funciona no TypeScript. A concorrência em um ambiente single-threaded é alcançada através de I/O não bloqueante e operações assíncronas.



Vamos considerar um exemplo usando Promise.allSettled() para execução concorrente de várias tarefas assíncronas com tratamento de erros:



interface TaskResult<T> {  status: 'fulfilled' | 'rejected';  value?: T;  reason?: Error;}

async function runConcurrentTasks<T>( tasks: Promise<T>[]): Promise<TaskResult<T>[]> { const results = await Promise.allSettled(tasks); return results.map(result => { if (result.status === 'fulfilled') { return { status: 'fulfilled', value: result.value }; } else { return { status: 'rejected', reason: result.reason }; } });}

// Usoconst task1 = fetchData('/api/users');const task2 = fetchData('/api/posts');const task3 = fetchData('/api/comments');

const results = await runConcurrentTasks([task1, task2, task3]);


2. Worker Threads no Node.js: Multithreading Real



Para tarefas intensivas em CPU (por exemplo, processamento de imagens, criptografia, cálculos complexos), são necessárias threads reais. No Node.js, isso é feito usando Worker Threads.



Vamos criar um Worker tipado com TypeScript:



// worker.tsimport { parentPort, workerData } from 'worker_threads';

interface WorkerInput { data: number[]; operation: 'sum' | 'multiply';}

interface WorkerOutput { result: number; duration: number;}

if (parentPort) { const input: WorkerInput = workerData; const start = performance.now(); let result: number; if (input.operation === 'sum') { result = input.data.reduce((acc, val) => acc + val, 0); } else { result = input.data.reduce((acc, val) => acc * val, 1); } const output: WorkerOutput = { result, duration: performance.now() - start }; parentPort.postMessage(output);}


Agora vamos criar um gerenciador para controlar vários Workers:



// threadPool.tsimport { Worker } from 'worker_threads';import path from 'path';

class ThreadPool<TInput, TOutput> { private workers: Worker[] = []; private taskQueue: Array<{ input: TInput; resolve: (value: TOutput) => void; reject: (reason?: any) => void; }> = [];

constructor( private workerScript: string, private poolSize: number = 4 ) { this.initialize(); }

private initialize(): void { for (let i = 0; i < this.poolSize; i++) { const worker = new Worker(this.workerScript); worker.on('message', (result: TOutput) => { const task = this.taskQueue.shift(); if (task) { task.resolve(result); } worker.postMessage(this.taskQueue[0]?.input); });

worker.on('error', (error) => { const task = this.taskQueue.shift(); if (task) { task.reject(error); } });

this.workers.push(worker); } }

async execute(input: TInput): Promise<TOutput> { return new Promise((resolve, reject) => { this.ta

Blogs

Book Recommendations