Fácil JavaScript
Ordem de execução com setTimeout e Promise
Enunciado
Escreva um programa que imprima na ordem correta: primeiro A (síncrono), depois B (microtarefa) e por último C (macrotarefa). Use console.log, Promise.resolve().then e setTimeout.
Requisitos
- Imprimir 'A' de forma síncrona
- Agendar 'B' como microtarefa usando Promise
- Agendar 'C' como macrotarefa usando setTimeout com delay 0
- A saída deve ser exatamente: A, B, C (cada um em uma linha)
Código inicial
// Complete o código para imprimir A, B, C na ordem correta
console.log('A');
// Agende B como microtarefa
// Agende C como macrotarefa
Saída esperada
A
B
C
Ver dica
Microtarefas são executadas antes de macrotarefas. Use Promise.resolve().then() para microtarefa e setTimeout(fn, 0) para macrotarefa.
Mostrar solução
// Imprime 'A' imediatamente (síncrono)
console.log('A');
// Agenda 'B' como microtarefa usando Promise
Promise.resolve().then(() => {
console.log('B');
});
// Agenda 'C' como macrotarefa usando setTimeout
setTimeout(() => {
console.log('C');
}, 0);
Passo a passo
console.log('A')é executado na call stack imediatamente, imprimindo 'A'.Promise.resolve().then(...)agenda o callback para a fila de microtarefas.setTimeout(..., 0)agenda o callback para a fila de tarefas (macrotarefas).- A call stack fica vazia após o último
console.logsíncrono. - O event loop verifica a fila de microtarefas primeiro e executa o callback da Promise, imprimindo 'B'.
- Depois de esvaziar as microtarefas, o event loop pega a macrotarefa e executa o callback do setTimeout, imprimindo 'C'.
Por que funciona
O event loop prioriza microtarefas sobre macrotarefas. Mesmo que o setTimeout tenha delay 0, ele só será executado após todas as microtarefas pendentes. Isso garante que 'B' (microtarefa) saia antes de 'C' (macrotarefa).
Erros comuns
- Achar que
setTimeout(fn, 0)executa imediatamente: Ele vai para a fila de tarefas e só roda depois das microtarefas. - Usar
setTimeoutsem delay:setTimeout(fn)tem delay 0 por padrão, mas ainda é macrotarefa. - Esquecer de retornar a Promise: Não é necessário aqui, mas em outros casos pode causar erros.
Outra forma de resolver
Usar queueMicrotask para agendar a microtarefa:
console.log('A');
queueMicrotask(() => console.log('B'));
setTimeout(() => console.log('C'), 0);
queueMicrotask é mais explícito para microtarefas, mas Promise.resolve().then é mais comum.
Saída esperada
A
B
C