Middle+
Ako funguje slučka udalostí (event loop) v web-API?
sobes.tech AI
Odpoveď od AI
Cyklus udalostí v JavaScript (v kontexte webového prehliadača) je mechanizmus, ktorý umožňuje vykonávať asynchrónne operácie bez blokovania hlavného vlákna. Skladá sa z niekoľkých komponentov:
- Heap (Hromada): Oblasť pamäti, kde sú uložené objekty.
- Call Stack (Zásobník volaní): Štruktúra dát LIFO, sledujúca vykonávanie synchronných funkcií.
- Web API (Webové API): Poskytované prehliadačom (DOM, AJAX,
setTimeout,setInterval, Event Listeners a pod.). Nie sú súčasťou JavaScriptového enginu. - Callback Queue (Fronta spätných volaní) / Task Queue (Fronta úloh): Fronta správ na vykonanie asynchrónnych úloh.
- Microtask Queue (Fronta mikroúloh): Prioritná fronta pre mikroúlohy (
Promise.then(),async/await,queueMicrotask). Vykonáva sa pred frontou úloh. - Event Loop (Udalostná slučka): Neustále kontroluje zásobník volaní a frontu. Ak je zásobník prázdny, presunie prvý obslužný rutinu z fronty mikroúloh na zásobník. Po vyprázdnení mikroúloh presunie prvý obslužný rutinu z fronty úloh na zásobník.
Proces vyzerá takto:
- Synchronný kód sa vykonáva a funkcie sa umiestňujú na zásobník.
- Keď sa objaví asynchrónna operácia (napríklad
setTimeout), odovzdá sa príslušnému Web API. Synchronný kód pokračuje. - Web API vykonáva operáciu na pozadí.
- Po dokončení asynchrónnej operácie je obsluha (callback) tejto operácie umiestnená do fronty úloh (pre bežné async operácie) alebo do fronty mikroúloh (pre promises).
- Udalostná slučka neustále kontroluje zásobník volaní. Ak je prázdny:
- Kontroluje frontu mikroúloh. Ak sú obslužné rutiny, presúva ich do zásobníka na vykonanie, kým mikroúlohy nie sú prázdne.
- Potom kontroluje frontu úloh. Ak sú obslužné rutiny, presúva prvú do zásobníka na vykonanie.
- Tento proces sa opakuje, umožňujúc vykonávanie asynchrónnych operácií bez blokovania.
Príklad s setTimeout:
// Tento kód sa vykonáva v zásobníku volaní
console.log('Start');
// setTimeout - Web API. Callback sa umiestňuje do fronty úloh po 0ms.
// Skutočné vykonanie môže byť oneskorené udalosťnou slučkou.
setTimeout(() => {
console.log('Timeout');
}, 0);
// Tento kód sa vykonáva v zásobníku volaní po setTimeout
console.log('End');
// Výstup:
// Start
// End
// Timeout
Príklad s promises:
// vykonáva sa v zásobníku volaní
console.log('A');
// promise. then() callback sa umiestňuje do mikro-úlohy
Promise.resolve().then(() => {
console.log('B');
});
// vykonáva sa v zásobníku volaní
console.log('C');
// Výstup:
// A
// C
// B
Poradie vykonávania: synchronný kód ('A', 'C'), potom sa vyprázdni mikro-úloha ('B'), následne fronta úloh.