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:
- Codul sincron se execută și funcțiile sunt plasate în stiva de apeluri.
- 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ă. - Web API efectuează operația în fundal.
- 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).
- 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.
- 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