Middle+
Hogyan működik az eseményciklus (event loop) a web-API-ban?
sobes.tech MI
Válasz az MI-től
A JavaScript eseményciklus (a webböngésző kontextusában) egy olyan mechanizmus, amely lehetővé teszi aszinkron műveletek végrehajtását anélkül, hogy blokkolná a fő végrehajtási szálat. Több összetevőből áll:
- Heap (Heap): Memóriaterület, ahol az objektumokat tárolják.
- Call Stack (Hívási verem): LIFO adatstruktúra, amely nyomon követi a szinkron függvények végrehajtását.
- Web API-k: A böngésző által biztosítottak (DOM, AJAX,
setTimeout,setInterval, Event Listeners stb.). Nem részei a JavaScript motornak. - Callback Queue (Visszahívási sor) / Task Queue (Feladat sor): Üzenetsor az aszinkron feladatok végrehajtására.
- Microtask Queue (Mikrofeladat sor): Prioritási sor mikrofeladatok számára (
Promise.then(),async/await,queueMicrotask). A feladat sor előtt kerül végrehajtásra. - Event Loop (Esemény ciklus): Folyamatosan ellenőrzi a hívási veremet és a sort. Ha a verem üres, áthelyezi az első kezelőt a mikrofeladat sorból a verembe. A mikrofeladat sor kiürülése után az első feladatot a feladat sorból a verembe helyezi.
A folyamat így működik:
- Szinkron kód futtatása, és a függvények a hívási verembe kerülnek.
- Amikor egy aszinkron művelet (pl.
setTimeout) található, átadódik a megfelelő Web API-nak. A szinkron kód végrehajtása folytatódik. - A Web API a műveletet háttérben végzi.
- Az aszinkron művelet befejezése után a kezelő (callback) az adott művelethez kerül a feladat sorba (normál async műveletek esetén) vagy a mikrofeladat sorba (promeszek esetén).
- Az esemény ciklus folyamatosan ellenőrzi a hívási veremet. Ha az üres:
- Ellenőrzi a mikrofeladat sort. Ha vannak kezelők, azokat a verembe helyezi végrehajtásra, amíg a mikrofeladat sor ki nem ürül.
- Ezután ellenőrzi a feladat sort. Ha vannak kezelők, az elsőt a verembe helyezi végrehajtásra.
- Ez a folyamat ismétlődik, lehetővé téve az aszinkron műveletek végrehajtását anélkül, hogy blokkolná a fő szálat.
Példa a setTimeout-tal:
// Ez a kód a hívási veremben fut
console.log('Start');
// setTimeout - Web API. A callback 0ms után kerül a feladat sorba.
// A tényleges végrehajtás a eseményciklus miatt késleltetett lehet.
setTimeout(() => {
console.log('Timeout');
}, 0);
// Ez a kód a setTimeout után fut a hívási veremben
console.log('End');
// Kimenet:
// Start
// End
// Timeout
Példa promeszekkel:
// A hívási veremben fut
console.log('A');
// Promis. A then() callback a mikrofeladat sorba kerül
Promise.resolve().then(() => {
console.log('B');
});
// A hívási veremben fut
console.log('C');
// Kimenet:
// A
// C
// B