Arhitectura Motorului JavaScript: Event Loop, Microtasks vs. Macrotasks în JavaScript

Cod asincron JavaScript Concurrency Model

Ghid complet de funcționare a Event Loop-ului în V8: diferența de prioritate dintre microtask-uri (Promise.then, queueMicrotask) și macrotask-uri (setTimeout, I/O) și prevenirea blocării firului UI.

Sintaxă
Call Stack -> Microtasks (Promises) -> Render -> Macrotasks (setTimeout)

Înțelegerea modului în care funcționează Event Loop în motoarele JavaScript (V8 din Chrome/Node.js, JavaScriptCore din Safari, SpiderMonkey din Firefox) este diferența dintre un dezvoltator junior și unul senior. Deși JavaScript rulează pe un singur fir de execuție principal (single-threaded), el realizează operațiuni asincrone masive fără blocare datorită cooperării dintre Call Stack, Web APIs și cele două cozi de execuție: Microtasks și Macrotasks.

Testul clasic de interviu: Ghicește ordinea afișării în consolă!
console.log("1. Start Sincron");

setTimeout(() => {
    console.log("2. Macrotask (setTimeout)");
}, 0);

Promise.resolve().then(() => {
    console.log("3. Microtask 1 (Promise)");
}).then(() => {
    console.log("4. Microtask 2 (Promise înlănțuit)");
});

queueMicrotask(() => {
    console.log("5. Microtask direct (queueMicrotask)");
});

console.log("6. Final Sincron");

// ORDINEA REALĂ DE AFIȘARE:
// 1. Start Sincron
// 6. Final Sincron
// 3. Microtask 1 (Promise)
// 5. Microtask direct (queueMicrotask)
// 4. Microtask 2 (Promise înlănțuit)
// 2. Macrotask (setTimeout)

De ce au Microtask-urile Prioritate Absolută

Regula de aur a ciclului Event Loop este:

  1. Execută codul sincron din Call Stack până când stiva este complet goală.
  2. Verifică Microtask Queue: dacă există sarcini (callback-uri de Promise, queueMicrotask, MutationObserver), execută TOATE microtask-urile până la golirea completă a cozii. Dacă un microtask adaugă alt microtask, acesta va fi executat în același ciclu!
  3. Dacă este momentul pentru actualizarea ecranului (la 60 sau 120 Hz), rulează etapa de Render / Paint a browserului.
  4. Extrage și execută exact UN SINGUR macrotask din Macrotask Queue (setTimeout, setInterval, evenimente I/O).
  5. Reia ciclul de la pasul 2.

Capcană Frecventă: Blocarea Browserului prin Microtask Loop Infinit

Dacă programezi recursiv un microtask (de exemplu o promisiune care se rezolvă la infinit chemând queueMicrotask), browserul se va bloca complet, deoarece Event Loop nu va ajunge niciodată la etapa de Render și nici la prelucrarea evenimentelor de click ale utilizatorului.