JavaScript Assincronia Intermediário
Event loop
O event loop é o mecanismo que permite ao JavaScript, que é single-threaded, executar tarefas assíncronas sem bloquear a thread principal. Ele coordena a call stack, a fila de tarefas (macrotarefas) e a fila de microtarefas, garantindo que o código seja executado na ordem correta.
A call stack é onde as funções são empilhadas para execução. Quando uma função assíncrona (como setTimeout ou uma Promise) é chamada, ela agenda um callback para ser executado depois. Callbacks de setTimeout vão para a fila de tarefas, enquanto callbacks de Promises (.then, await) vão para a fila de microtarefas.
O event loop verifica constantemente se a call stack está vazia. Se estiver, ele primeiro esvazia toda a fila de microtarefas, e só depois pega uma tarefa da fila de tarefas. Isso explica por que Promise.resolve().then() executa antes de setTimeout(fn, 0), mesmo que ambos sejam agendados para "depois".
Entender essa ordem é crucial para prever a saída de programas assíncronos e evitar bugs sutis de timing.
Pontos-chave
- A call stack executa funções de forma síncrona e bloqueante.
- Microtarefas (Promises) têm prioridade sobre macrotarefas (setTimeout).
- O event loop só processa a fila de tarefas após esvaziar a fila de microtarefas.
setTimeout(fn, 0)não executa imediatamente; vai para a fila de tarefas.- Ordem de execução: síncrono → microtarefas → macrotarefas.
// Exemplo que demonstra a ordem de execução no event loop
console.log('1. Início síncrono');
// setTimeout agenda uma macrotarefa
setTimeout(() => {
console.log('5. setTimeout 0 (macrotarefa)');
}, 0);
// Promise agenda uma microtarefa
Promise.resolve().then(() => {
console.log('3. Promise.then (microtarefa)');
});
// Outra microtarefa
Promise.resolve().then(() => {
console.log('4. Outra Promise.then (microtarefa)');
});
console.log('2. Fim síncrono');
// Saída esperada:
// 1. Início síncrono
// 2. Fim síncrono
// 3. Promise.then (microtarefa)
// 4. Outra Promise.then (microtarefa)
// 5. setTimeout 0 (macrotarefa)