Concorrência e Multithreading em TypeScript: Guia Completo

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: da teoria à prática



As aplicações web modernas enfrentam cada vez mais a necessidade de processar grandes volumes de dados e executar operações que consomem muitos recursos sem bloquear a interface do usuário. O TypeScript, sendo uma extensão do JavaScript, herda seu modelo de execução single-thread, mas também fornece ferramentas poderosas para organizar concorrência e multithreading. Neste artigo, vamos explorar como usar esses recursos de forma eficaz em seus projetos.



Entendendo concorrência e multithreading



Antes de nos aprofundarmos no código, é importante diferenciar dois conceitos-chave:



  • Concorrência — a capacidade do sistema de lidar com várias tarefas em períodos de tempo sobrepostos, mas não necessariamente simultaneamente. Isso é alcançado através da rápida alternância de contexto.
  • Multithreading — a execução paralela de várias threads em diferentes núcleos da CPU. No Node.js, isso é implementado através de Worker Threads.


O TypeScript opera no ambiente Node.js, onde a thread principal processa eventos através do Event Loop. Para cálculos pesados, isso pode se tornar um gargalo.



Assincronia e Promise: a base da concorrência



O nível básico de concorrência em TypeScript é construído sobre async/await e Promise. Esses mecanismos permitem não bloquear a thread principal durante a espera por operações de I/O.



// Exemplo de carregamento assíncrono de dadosinterface User {  id: number;  name: string;}

async function fetchUser(id: number): Promise<User> { const response = await fetch(`https://api.example.com/users/${id}`); return response.json();}

// Execução paralela de múltiplas requisiçõesasync function loadUsers(): Promise<User[]> { const userIds = [1, 2, 3, 4, 5]; const promises = userIds.map(id => fetchUser(id)); return Promise.all(promises);}

loadUsers().then(users => { console.log('Usuários carregados:', users.length);});


Promise.all inicia todas as promises simultaneamente, mas elas são executadas em uma única thread. Isso é ideal para tarefas de I/O, mas não é adequado para operações intensivas de CPU.



Worker Threads: verdadeiro multithreading



Para executar cálculos pesados sem bloquear a thread principal, use Worker Threads. Este é um módulo embutido do Node.js que cria threads separadas com sua própria memória.



Vamos criar um exemplo de cálculo de números de Fibonacci em uma thread separada:



// fibonacci.worker.tsimport { parentPort } from 'worker_threads';

function fibonacci(n: number): number { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2);}

parentPort?.on('message', (n: number) => { const result = fibonacci(n); parentPort?.postMessage(result);});


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

function runFibonacciInWorker(n: number): Promise<number> { return new Promise((resolve, reject) => { const worker = new Worker(path.resolve(__dirname, 'fibonacci.worker.ts')); worker.postMessage(n); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`Worker parou com código de saída ${code}`)); }); });}

async function main() { console.time('fibonacci'); const result = await runFibonacciInWorker(40); console.timeEnd('fibonacci'); console.log(`Fibonacci(40) = ${result}`);}

main();


Observe: para executar workers em TypeScript, será necessária a compilação para JavaScript. Você pode usar ts-node ou compilação prévia.



SharedArrayBuffer: memória compartilhada entre threads



Quando as threads precisam trocar grandes volumes de da

Blogs

Book Recommendations