Sobes.tech
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:

  1. Szinkron kód futtatása, és a függvények a hívási verembe kerülnek.
  2. 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.
  3. A Web API a műveletet háttérben végzi.
  4. 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).
  5. 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.
  6. 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