JavaScript: Microtasks e Macrotasks

Duas histórias no mesmo Event Loop e suas prioridades

Eduardo Rabelo
2 min readJun 28, 2019
Caótico Mundo Lindo do Event Loop em JavaScript — Créditos da imagem

Dentro do Event Loop do JavaScript, existem dois tipos de tarefas com prioridades bem diferentes, por exemplo:

  • Microtasks: process.nextTick, Promises, Object.observe, MutationObserver
  • Macrotasks: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering

Mas qual a diferença prática entre os dois? Podemos resumir na seguinte afirmação:

Se alguma Microtask estiver pendente na fila para o Event Loop, ela será executada antes do início do próximo loop (no final do loop atual). Já as Macrotask serão executadas apenas no próximo loop.

Essa definição é importante, pois o resultado de algumas operações podem surpreender os não familiarizados com a engine do JavaScript.

Com isso em mente, qual será o resultado do trecho de código abaixo?

console.log('01-Console');setTimeout(_ => console.log('02-Timeout'), 0);Promise.resolve().then(_ => console.log('03-Promise'));console.log('04-Console');

Antes de olhar a resposta abaixo, você consegue imaginar a saída desse programa?

Uma hora ou outra precisamos saber a resposta…

Ao executar o trecho acima, teremos o seguinte resultado:

$ node tasks.js01-Console
04-Console
03-Promise
02-Timeout

Colocando algumas anotações no código, temos:

console.log('01-Console'); // [A]setTimeout(_ => console.log('02-Timeout'), 0); // [B]Promise.resolve().then(_ => console.log('03-Promise')); // [C]console.log('04-Console'); // [D]
  • [A]: Executado diretamente na “main thread”, síncrono
  • [B]: Enfileirado como uma tarefa futura, prioridade “macrotask”, será executado apenas no próximo loop
  • [C]: Enfileirado como uma tarefa futura, prioridade “microtask”, será executado imediatamente após todas as tarefas/tasks do loop atual e antes do próximo loop
  • [D]: Executado diretamente na “main thread”, síncrono

--

--