Aszinkron JavaScript és Event Loop
Callback, Promise, async/await és az event loop – hogyan működik az aszinkron JavaScript a motor alatt.
Aszinkron JavaScript és Event Loop
Ez az oldal a teljes jegyzet 12–13. fejezetét foglalja össze: aszinkron minták (callback, Promise,
async/await) és az event loop működése.
Forrás:content/javascript/javascript-full.mdx.
1. Miért kell az aszinkronitás?
A JavaScript single‑threaded – egyszerre egy dolgot csinál. Ha egy hosszú művelet (pl. hálózati kérés) blokkolná a fő szálat, a teljes UI "megfagyna".
Aszinkron kóddal:
- a hosszú művelet külön környezetben fut (Web APIs / Node APIs),
- amikor elkészül, egy queue‑ba kerül,
- az event loop a fő szál felszabadulása után futtatja a callbacket.
2. Callback – a klasszikus megközelítés
function adatLetoltes(callback) {
setTimeout(() => {
const adat = { nev: "Adam" };
callback(adat);
}, 1000);
}
adatLetoltes(function(adat) {
console.log(adat.nev); // "Adam" – 1 mp múlva
});Callback hell probléma:
felhasznaloLetolt(id, function(user) {
profilLetolt(user.profilId, function(profil) {
kepLetolt(profil.kepId, function(kep) {
console.log(kep); // 3 szint mélyen
});
});
});Nehéz olvasni, nehéz hibát kezelni → ezért jött a Promise.
3. Promise – modern alap
Promise = egy jövőbeli érték ígérete:
pending→ folyamatban,fulfilled→ sikeres,rejected→ hiba.
const igerem = new Promise((resolve, reject) => {
setTimeout(() => {
const siker = true;
if (siker) {
resolve({ nev: "Adam" });
} else {
reject(new Error("Valami hiba történt"));
}
}, 1000);
});
igerem
.then(adat => console.log(adat.nev))
.catch(hiba => console.error(hiba))
.finally(() => console.log("Kész"));Promise láncolás:
felhasznaloLetolt(id)
.then(user => profilLetolt(user.profilId))
.then(profil => kepLetolt(profil.kepId))
.then(kep => console.log(kep))
.catch(hiba => console.error(hiba));4. async / await – szinkronszerű szintaxis
async/await csak cukor a Promise‑okra, de sokkal olvashatóbb:
async function adatokLekeres(id) {
try {
const user = await felhasznaloLetolt(id);
const profil = await profilLetolt(user.profilId);
const kep = await kepLetolt(profil.kepId);
console.log(kep);
} catch (hiba) {
console.error("Hiba:", hiba);
}
}
adatokLekeres(123);Fontos:
asyncfüggvény mindig Promise‑t ad vissza,awaitcsakasyncfüggvényben használható,try/catchfogja a Promise‑okrejectágát.
Párhuzamos futtatás – Promise.all
async function parhuzamos() {
// Lassú – sorban fut
const a = await lekerA();
const b = await lekerB();
// Gyorsabb – párhuzamosan indul
const [a2, b2] = await Promise.all([lekerA(), lekerB()]);
}5. fetch – hálózati kérések
async function felhasznalokLeker() {
try {
const valasz = await fetch("https://api.example.com/users");
if (!valasz.ok) {
throw new Error(`HTTP hiba: ${valasz.status}`);
}
const adatok = await valasz.json();
return adatok;
} catch (hiba) {
console.error("Hálózati hiba:", hiba);
throw hiba;
}
}Minta:
fetch→res.okellenőrzés →res.json()→try/catch.
6. Event Loop – hogyan ütemeződik minden?
Fő szereplők
- Call Stack – szinkron kód futtatása (LIFO verem).
- Web APIs / Node APIs – környezet specifikus aszinkron műveletek (
setTimeout,fetch, DOM eventek). - Task Queue (Macrotask Queue) – pl.
setTimeout,setInterval, DOM event callbackek. - Microtask Queue – Promise callbackek (
.then,.catch,.finally,queueMicrotask).
Prioritás: Call Stack → Microtask Queue → Task Queue.
Klasszikus példakód
console.log("1");
setTimeout(() => {
console.log("2");
}, 0);
Promise.resolve().then(() => {
console.log("3");
});
console.log("4");Kimenet: 1, 4, 3, 2
Miért?
console.log("1")– azonnal fut → "1"setTimeoutcallback megy a Web APIs‑ba, majd 0 ms után a Task Queue‑ba.Promise.resolve().then(...)callback a Microtask Queue‑ba kerül.console.log("4")– azonnal fut → "4"- Call Stack kiürül → event loop:
- először a Microtask Queue összes elemét futtatja → "3",
- ezután jön a Task Queue → "2".
Mikro vs makrotask
setTimeout(() => console.log("setTimeout"), 0);
Promise.resolve().then(() => console.log("Promise"));Kimenet:
Promise
setTimeout
Szabály: minden render / stack kiürülés után előbb kerülnek lefuttatásra a microtaskok (Promise callbackek), csak utána a macrotaskok (pl. setTimeout).
Összefoglaló – Aszinkron JS + Event Loop
- Callback: egyszerű, de callback hell‑hez vezethet.
- Promise: láncolható, olvashatóbb, mint callbackek.
async/await: a Promise‑okra épül, de szinkron stílusú kódot ad.- Event loop:
- JS single‑threaded, de a környezet (böngésző/Node) segít az aszinkronitásban,
- Microtask Queue (Promise) prioritást élvez a Task Queue (setTimeout) előtt.
Következő oldal:
DOM, böngésző API-k és hibakezelés →