JavaScript: Microtasks e Macrotasks
Duas histórias no mesmo Event Loop e suas prioridades
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?
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
📚 Links Relacionados
- https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
- https://blog.risingstack.com/node-js-at-scale-understanding-node-js-event-loop/
- https://javascript.info/microtask-queue
- https://github.com/nodejs/node/issues/22257
- https://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context