Middle+
Jak działa pętla zdarzeń (event loop) w API web?
sobes.tech AI
Odpowiedź od AI
Pętla zdarzeń w JavaScript (w kontekście przeglądarki internetowej) to mechanizm umożliwiający wykonywanie operacji asynchronicznych bez blokowania głównego wątku wykonawczego. Składa się z kilku komponentów:
- Heap (Stos): Obszar pamięci, w którym przechowywane są obiekty.
- Call Stack (Stos wywołań): Struktura danych LIFO, śledząca wykonywanie funkcji synchronicznych.
- Web APIs: Dostarczane przez przeglądarkę (DOM, AJAX,
setTimeout,setInterval, Event Listeners itp.). Nie są częścią silnika JavaScript. - Callback Queue (Kolejka callback): / Task Queue (Kolejka zadań): Kolejka wiadomości do wykonywania operacji asynchronicznych.
- Microtask Queue (Kolejka mikro-zadań): Priorytetowa kolejka dla mikro-zadań (
Promise.then(),async/await,queueMicrotask). Wykonywana przed kolejką zadań. - Event Loop (Pętla zdarzeń): Nieustannie sprawdza stos wywołań i kolejkę. Jeśli stos jest pusty, przenosi pierwszy obsługiwacz z kolejki mikro-zadań na stos. Po opróżnieniu kolejki mikro-zadań, przenosi pierwszy obsługiwacz z kolejki zadań na stos.
Proces działa następująco:
- Kod synchroniczny jest wykonywany, a funkcje umieszczane na stosie wywołań.
- Gdy napotkamy operację asynchroniczną (np.
setTimeout), jest ona przekazywana do odpowiedniego Web API. Wykonanie kodu synchronicznego kontynuuje się. - Web API wykonuje operację w tle.
- Po zakończeniu operacji asynchronicznej, obsługiwacz (callback) tej operacji jest umieszczany w kolejce zadań (dla zwykłych operacji async) lub kolejce mikro-zadań (dla promes).
- Pętla zdarzeń nieustannie sprawdza stos wywołań. Jeśli jest pusty:
- Sprawdza kolejkę mikro-zadań. Jeśli są obsługiwacze, przenosi je do stosu wywołań do wykonania, aż kolejka mikro-zadań będzie pusta.
- Następnie sprawdza kolejkę zadań. Jeśli są obsługiwacze, przenosi pierwszy do stosu wywołań do wykonania.
- Proces ten powtarza się, umożliwiając wykonywanie operacji asynchronicznych bez blokowania głównego wątku.
Przykład z setTimeout:
// Kod wykonywany na stosie wywołań
console.log('Start');
// setTimeout - Web API. Callback umieszczany w kolejce zadań po 0ms.
// Rzeczywiste wykonanie może być opóźnione przez pętlę zdarzeń.
setTimeout(() => {
console.log('Timeout');
}, 0);
// Kod wykonywany na stosie wywołań po setTimeout
console.log('Koniec');
// Wynik:
// Start
// Koniec
// Timeout
Przykład z promesami:
// Wykonywany na stosie wywołań
console.log('A');
// Promesa. Callback then() umieszczany w kolejce mikro-zadań
Promise.resolve().then(() => {
console.log('B');
});
// Wykonywany na stosie wywołań
console.log('C');
// Wynik:
// A
// C
// B