Sobes.tech
Middle+

Cum funcționează bucla de evenimente (event loop) în API-ul web?

sobes.tech AI

Răspuns de la AI

Ciclul evenimentelor în JavaScript (în contextul browser-ului web) este un mecanism care permite executarea operațiunilor asincrone fără blocarea fluxului principal de execuție. Este compus din mai multe componente:

  • Heap (Heap): Zonă de memorie unde sunt stocate obiectele.
  • Call Stack (Stiva de apeluri): Structură de date LIFO care urmărește execuția funcțiilor sincrone.
  • Web APIs: Oferite de browser (DOM, AJAX, setTimeout, setInterval, Event Listeners etc.). Nu fac parte din motorul JavaScript.
  • Callback Queue (Coada de callback): / Task Queue (Coada de sarcini): Coada de mesaje pentru executarea sarcinilor asincrone.
  • Microtask Queue (Coada de microtask-uri): Coadă prioritară pentru microtask-uri (Promise.then(), async/await, queueMicrotask). Se execută înaintea cozii de sarcini.
  • Event Loop (Ciclul evenimentelor): Verifică continuu stiva de apeluri și coada. Dacă stiva este goală, mută primul handler din coada de microtask-uri în stivă. După ce coada de microtask-uri este goală, mută primul handler din coada de sarcini în stivă.

Procesul funcționează astfel:

  1. Codul sincron se execută și funcțiile sunt plasate în stiva de apeluri.
  2. Când se întâlnește o operație asincronă (de exemplu, setTimeout), aceasta este transferată către Web API corespunzător. Executarea codului sincron continuă.
  3. Web API efectuează operația în fundal.
  4. După finalizarea operației asincrone, handler-ul (callback-ul) acestei operații este plasat în coada de sarcini (pentru operații asincrone obișnuite) sau în coada de microtask-uri (pentru promisiuni).
  5. Event Loop verifică continuu stiva de apeluri. Dacă aceasta este goală:
    • Verifică coada de microtask-uri. Dacă există handler-e, le mută în stiva de apeluri pentru execuție, până când coada de microtask-uri devine goală.
    • Apoi verifică coada de sarcini. Dacă există handler-e, mută primul în stiva de apeluri pentru execuție.
  6. Acest proces se repetă, permițând executarea operațiunilor asincrone fără blocarea thread-ului principal.

Exemplu cu setTimeout:

// Acest cod se execută în stiva de apeluri
console.log('Start');

// setTimeout - Web API. Callback-ul este plasat în coada de sarcini după 0ms.
// Execuția efectivă poate fi întârziată de ciclul de evenimente.
setTimeout(() => {
  console.log('Timeout');
}, 0);

// Acest cod se execută în stiva de apeluri după setTimeout
console.log('End');

// Output:
// Start
// End
// Timeout

Exemplu cu promisiuni:

// Se execută în stiva de apeluri
console.log('A');

// Promisiune. Callback-ul then() este plasat în coada de microtask-uri
Promise.resolve().then(() => {
  console.log('B');
});

// Se execută în stiva de apeluri
console.log('C');

// Output:
// A
// C
// B