Concorrência e Multithreading em JavaScript: do A ao Z

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 JavaScript: do A ao Z



JavaScript historicamente é uma linguagem single-thread, operando dentro do paradigma de programação orientada a eventos. No entanto, o JavaScript moderno (especialmente no ambiente Node.js) oferece ferramentas poderosas para trabalhar com concorrência e multithreading. Neste artigo, vamos explorar como funcionam Event Loop, Promises, async/await, Worker Threads e clusterização, e como usar esses mecanismos para melhorar o desempenho das suas aplicações.



1. Event Loop: a base da concorrência em JavaScript



O Event Loop é o coração do modelo assíncrono do JavaScript. Ele permite processar múltiplas operações sem bloquear o fluxo principal de execução. No Node.js, o Event Loop gerencia filas de tarefas (macrotasks e microtasks), garantindo entrada/saída não bloqueante.



Exemplo de funcionamento do Event Loop:



console.log('Início');

setTimeout(() => { console.log('Timer 1');}, 0);

process.nextTick(() => { console.log('nextTick');});

Promise.resolve().then(() => { console.log('Promise');});

console.log('Fim');

// Saída:// Início// Fim// nextTick// Promise// Timer 1


É importante entender a ordem de execução: código síncrono → microtasks (process.nextTick, Promise.then) → macrotasks (setTimeout, setInterval).



2. Promises e async/await: gerenciando a assincronicidade



Promises são objetos que representam o resultado de uma operação assíncrona. Elas permitem evitar o "callback hell" e construir cadeias de chamadas. async/await é um açúcar sintático sobre Promises, tornando o código assíncrono semelhante ao síncrono.



Exemplo com async/await:



const fetchData = async (url) => {  const response = await fetch(url);  if (!response.ok) {    throw new Error(`Erro HTTP: ${response.status}`);  }  return await response.json();};

const main = async () => { try { const data = await fetchData('https://api.example.com/data'); console.log('Dados recebidos:', data); } catch (error) { console.error('Erro:', error.message); }};

main();


Essa abordagem permite executar múltiplas operações assíncronas em paralelo usando Promise.all():



const [user, posts] = await Promise.all([  fetchUser(userId),  fetchPosts(userId)]);console.log(user, posts);


3. Worker Threads: verdadeiro multithreading no Node.js



A partir do Node.js 10.5.0, o módulo worker_threads oferece a capacidade de criar threads reais para executar tarefas intensivas em CPU. Cada Worker opera em uma thread separada com sua própria instância V8.



Exemplo de criação de Worker:



// main.jsconst { Worker } = require('worker_threads');

const runWorker = (workerData) => { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData });

worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker parou com código ${code}`)); } }); });};

const main = async () => { const result = await runWorker({ iterations: 1000000 }); console.log('Resultado:', result);};

main();


// worker.jsconst { parentPort, workerData } = require('worker_threads');

const heavyComputation = (iterations) => { let result = 0; for (let i = 0; i < iterations; i++) { result += Math.sqrt(i); } return result;};

const result = heavyComputation(workerData.iterations);parentPort.postMessage(result);


Worker Threads são ideais para tarefas que bloqueiam o Event Loop: processamento de imagens, cálculos matemáticos, análise de arquivos grandes.



4. Clusterização: escalando para múltiplos processos

\

Blogs

Book Recommendations