Pętla zdarzeń: call stack, kolejka, mikrozadania
Proszę prześledzić wykonywanie kodu JavaScript: stos wywołań, kolejkę zadań i mikrozadania pochodzące z Promises, a także zrozumieć, dlaczego interfejs nie blokuje się podczas operacji asynchronicznych.
Pętla zdarzeń: call stack, kolejka, mikrozadania to bezpłatna lekcja Frontend Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Frontend Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Frontend Academy zawiera 4 lekcji w sumie.
JavaScript działa jednowątkowo
JavaScript działa w jednym wątku — może wykonywać tylko jeden fragment kodu naraz. Mimo to obsługuje tysiące operacji asynchronicznych (żądania sieciowe, liczniki czasu i zdarzenia interfejsu użytkownika) bez blokowania. Jak? Dzięki pętli zdarzeń.
Stos wywołań
Stos wywołań służy JavaScriptowi do śledzenia aktualnie wykonywanej funkcji. Gdy funkcja jest wywoływana, na stos trafia ramka. Gdy funkcja zwraca wynik, ramka jest zdejmowana ze stosu. Jeśli stos się przepełni (na przykład w wyniku nieskończonej rekurencji), wystąpi przepełnienie stosu.
function c() { /* does something */ }
function b() { c(); }
function a() { b(); }
a();
// Call stack during c():
// c ← top
// b
// a
// (anonymous)Web API — przekazywanie pracy
Gdy JavaScript wywołuje funkcję asynchroniczną (setTimeout, fetch, addEventListener), praca jest przekazywana do Web API w przeglądarce. Silnik JavaScriptu przechodzi do następnej linii — nie czeka.
console.log('1');
setTimeout(() => console.log('2'), 0); // handed to Web API
console.log('3');
// Output: 1, 3, 2Kolejka zadań (kolejka makrozadań)
Gdy operacja Web API dobiegnie końca (timer zadziała, fetch zostanie rozstrzygnięty), funkcja zwrotna trafia do kolejki zadań (kolejki makrozadań). Pętla zdarzeń przenosi funkcję zwrotną na stos wywołań dopiero wtedy, gdy stos jest pusty.
Kolejka mikrozadań
Promises korzystają z kolejki mikrozadań — kolejki o wysokim priorytecie. Po zakończeniu każdego zadania i przed pobraniem następnego wszystkie oczekujące mikrozadania zostają wykonane. Mikrozadania zawsze wykonują się przed następnym makrozadaniem.
console.log('1');
setTimeout(() => console.log('timeout'), 0); // macrotask
Promise.resolve().then(() => console.log('promise')); // microtask
console.log('2');
// Output: 1, 2, promise, timeoutPętla zdarzeń w działaniu
Algorytm pętli zdarzeń: 1) Wykonaj bieżące zadanie ze stosu wywołań, aż stos będzie pusty. 2) Wykonaj wszystkie mikrozadania z kolejki. 3) Opcjonalnie wyrenderuj interfejs. 4) Pobierz następne makrozadanie i powtórz.
queueMicrotask()
queueMicrotask(fn) planuje wykonanie funkcji zwrotnej w kolejce mikrozadań bez tworzenia Promise. Rzadko trzeba wywoływać ją bezpośrednio, ale warto rozumieć, jak biblioteki implementują planowanie zadań.
queueMicrotask(() => console.log('microtask'));
console.log('sync');
// Output: sync, microtaskDlaczego długie zadania zamrażają interfejs
Jeśli zadanie synchroniczne wykonuje się zbyt długo (na przykład ciasna pętla przetwarzająca dużą ilość danych), pętla zdarzeń nie może obsługiwać zdarzeń interfejsu ani renderowania. Strona zostaje zamrożona. Należy podzielić długą pracę na fragmenty za pomocą setTimeout, aby oddać sterowanie pętli zdarzeń.
// Bad — blocks the UI for seconds:
for (let i = 0; i < 10_000_000; i++) { /* heavy work */ }
// Better — yield periodically:
async function processInChunks(items) {
for (let i = 0; i < items.length; i++) {
process(items[i]);
if (i % 100 === 0) await new Promise(r => setTimeout(r, 0)); // yield
}
}Web Workers — prawdziwa równoległość
Do zadań intensywnie obciążających procesor należy użyć Web Worker — osobnego wątku z własną pętlą zdarzeń. Workery komunikują się z głównym wątkiem za pomocą postMessage. Brak współdzielonej pamięci oznacza brak wyścigów.
requestAnimationFrame
requestAnimationFrame(callback) planuje wykonanie funkcji zwrotnej przed kolejnym odświeżeniem obrazu przez przeglądarkę. Należy używać go do animacji sterowanych przez JavaScript — synchronizuje się z częstotliwością odświeżania ekranu (zwykle 60fps).
function animate(timestamp) {
// update positions based on timestamp
element.style.transform = `translateX(${timestamp * 0.1 % 400}px)`;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);Wizualizacja pętli zdarzeń
Interaktywne demo dostępne pod adresem latentflip.com/loupe umożliwia wklejenie kodu i obserwowanie stosu wywołań, Web API, kolejki zadań oraz pętli zdarzeń w zwolnionym tempie. Jest niezbędne do wyrobienia sobie intuicji.
Szybkie sprawdzenie
Po rozstrzygnięciu Promise funkcja zwrotna .then() jest wykonywana w której kolejce?
Podsumowanie: pętla zdarzeń
JavaScript działa w jednym wątku. Praca asynchroniczna trafia do Web APIs. Funkcje zwrotne wracają przez kolejkę zadań (setTimeout, funkcje zwrotne fetch) lub kolejkę mikrozadań (Promises). Pętla zdarzeń wykonuje mikrozadania po każdym zadaniu, przed kolejnym renderowaniem lub makrozadaniem. Długi kod synchroniczny blokuje wszystko.
Często zadawane pytania
Czy lekcja „Pętla zdarzeń: call stack, kolejka, mikrozadania” jest bezpłatna?
Tak — pełny tekst „Pętla zdarzeń: call stack, kolejka, mikrozadania” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Frontend Academy, przejdź na CoddyKit PRO. Kurs Frontend Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Pętla zdarzeń: call stack, kolejka, mikrozadania”?
Proszę prześledzić wykonywanie kodu JavaScript: stos wywołań, kolejkę zadań i mikrozadania pochodzące z Promises, a także zrozumieć, dlaczego interfejs nie blokuje się podczas operacji asynchroniczny… Ćwiczysz Frontend Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Frontend Academy?
Nie wymagamy żadnego doświadczenia. Frontend Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Pętla zdarzeń: call stack, kolejka, mikrozadania”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Frontend Academy?
Tak. Każda lekcja Frontend Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Pętla zdarzeń: call stack, kolejka, mikrozadania
- Callbacki i callback hell
- Promises: then, catch, finally, Promise.all
- async/await i obsługa błędów