Event Loop, Microtasks e Macrotasks: O Modelo de Execução do JavaScript
O quiz que separa quem entende de quem decora
Cole este trecho no console do navegador ou no Node.js e tente prever a ordem de saída antes de executar:
console.log("1: script start");setTimeout(() => { console.log("2: setTimeout");}, 0);Promise.resolve() .then(() => { console.log("3: promise then"); }) .then(() => { console.log("4: promise then chained"); });queueMicrotask(() => { console.log("5: queueMicrotask");});console.log("6: script end");
A saída é:
1: script start6: script end3: promise then5: queueMicrotask4: promise then chained2: setTimeout
Se você errou a posição do setTimeout em relação às Promises, o problema não é falta de prática: é que a maioria dos materiais mistura três conceitos distintos (call stack, microtask queue e task queue) como se fossem a mesma coisa.
O que é o event loop (sem analogia de garçom)
O event loop é um algoritmo de scheduling implementado pelo runtime, não pela linguagem. A especificação ECMAScript define a semântica de Jobs (microtasks), mas quem implementa o loop de fato é o runtime: o V8 delega para o embedder (Chromium usa libevent, Node.js usa libuv).
O ciclo simplificado funciona assim:
- Executa todo o código síncrono da call stack até esvaziar.
- Drena a microtask queue inteira (Promises,
queueMicrotask,MutationObserverno browser). - Pega UMA tarefa da macrotask queue (também chamada de task queue):
setTimeout,setInterval, I/O callbacks,setImmediate(Node.js). - Volta ao passo 2.
O ponto que gera confusão: microtasks são drenadas completamente entre cada macrotask. Isso significa que uma microtask que agenda outra microtask adia indefinidamente a próxima macrotask.
Este é um trecho. O tutorial completo, com todos os exemplos, os testes e as limitações, está em https://www.vivodecodigo.com.br/backend/event-loop-microtasks-macrotasks-modelo-execucao-javascript. Se você já passou por esse problema de outro jeito, conta nos comentários: a discussão aqui ajuda a melhorar o artigo.
