Concorrência em TypeScript: threads, goroutines e async/await — entendendo na prática

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 em TypeScript: do Event Loop aos Web Workers

\n\n

Você já notou como seu navegador ou aplicação Node.js "trava" durante a execução de uma operação matemática complexa ou ao processar um grande JSON? Aquela sensação familiar de impotência, quando a interface para de responder a cliques e o servidor para de responder a novas requisições. Tudo isso porque, por padrão, JavaScript (e seu irmão mais rigoroso TypeScript) é uma linguagem de thread única. Mas isso não significa que estamos condenados a programas lentos. Pelo contrário, o uso adequado da concorrência em TypeScript permite criar aplicações rápidas e responsivas.

\n\n

Neste artigo, não vamos apenas listar termos. Vamos entender como realmente funcionam async/await, o que está por baixo do capô do Event Loop, se é possível usar "goroutines" em TypeScript como em Go, e quando devemos usar threads reais através de Web Workers. Vamos lá!

\n\n

1. Assincronia vs Paralelismo: qual a diferença?

\n\n

Antes de nos aprofundarmos no código, vamos definir os termos. Muitos confundem esses conceitos, e isso é um erro.

\n\n
    \n
  • Assincronia (concorrência) — é a capacidade do programa de iniciar uma tarefa, mudar para outra enquanto a primeira espera (por exemplo, uma resposta do servidor) e retornar a ela mais tarde. Em um dado momento, apenas uma instrução é executada.
  • \n
  • Paralelismo — é a execução de duas ou mais tarefas literalmente ao mesmo tempo, em diferentes núcleos da CPU.
  • \n
\n\n

TypeScript nos oferece assincronia nativamente. Já o paralelismo exige a criação de threads separadas — no navegador, são os Web Workers; no Node.js, são os worker_threads. Lembre-se dessa diferença, caso contrário, você corre o risco de escrever um código que "trava" devido ao bloqueio da thread principal.

\n\n

2. Event Loop e callbacks — a base da concorrência em TypeScript

\n\n

O grande segredo da assincronia em JavaScript/TypeScript é o Event Loop (ciclo de eventos). Imagine que você tem uma fila de tarefas. A thread principal pega uma tarefa, a executa; se for síncrona, o resultado é imediato. Se for uma operação assíncrona (como setTimeout ou fetch), ela é enviada "para o lado" (para a Web API ou libuv), enquanto a thread principal continua executando o próximo código.

\n\n

Quando a operação assíncrona termina, seu callback entra em uma fila (Task Queue ou Microtask Queue). O Event Loop verifica constantemente se a pilha de chamadas está vazia; se estiver, ele pega a primeira tarefa da fila e a executa.

\n\n
// Exemplo simples que demonstra isso\nconsole.log('1. Início');\n\nsetTimeout(() => {\n    console.log('3. Timer disparou');\n}, 0);\n\nPromise.resolve().then(() => {\n    console.log('2. Microtask executada');\n});\n\nconsole.log('4. Fim');\n\n// Saída: 1, 4, 2, 3
\n\n

Observe que a Promise (microtask) foi executada antes do setTimeout (macrotask), mesmo com o timer tendo atraso de 0 ms. Esse é um conhecimento importante para a otimização em TypeScript.

\n\n

3. Async/Await — o açúcar que muda tudo

\n\n

Com o surgimento do ES2017, o mundo JS se dividiu entre "antes" e "depois". Async/await é um açúcar sintático sobre as Promises, que torna o código assíncrono semelhante ao síncrono. Ele não adiciona threads, mas aumenta radicalmente a legibilidade.

\n\n
// Função que simula um atraso\nfunction delay(ms: number): Promise<void> {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// Função assíncrona usando async/await\nasync function fetchUserData(userId: number): Promise<string> {\n    console.log(`Solicitando dados do usuário ${userId}...`);\n    await delay(2000); // Simula uma requisição de rede\n    return `Dados do usuário ${userId}`;\n}\n\nasync function main() {\n    console.log('Início');\n    const user1 = await fetchUserData(1);\n    console.log(                

Blogs

Book Recommendations