Cześć! Jeśli kiedykolwiek zastanawiałeś się, jak JavaScript radzi sobie z asynchronicznością, mimo że jest językiem jednowątkowym, to trafiłeś w dobre miejsce.
Dzisiaj pogadamy o Event Loop – sercu asynchronicznego działania JavaScriptu. Przygotuj się na podróż przez świat kodu, gdzie wszystko ma swoje miejsce i czas! ⏳
Jednowątkowy, ale asynchroniczny? 🤔
Zacznijmy od podstaw. JavaScript jest językiem jednowątkowym, co oznacza, że w danym momencie wykonuje tylko jedno zadanie.
Więc jak to możliwe, że możemy wykonywać operacje asynchroniczne, takie jak pobieranie danych z serwera, bez blokowania całej aplikacji?
Tu właśnie wkracza Event Loop!
źródło:https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif
Event Loop – co to takiego? 💡
Event Loop to mechanizm w JavaScript, który zarządza kolejnością wykonywania zadań, zwłaszcza tych asynchronicznych.
Dzięki niemu nasz kod może reagować na zdarzenia w odpowiednim momencie, nie blokując przy tym głównego wątku.
Wyobraź sobie to tak: masz stos wywołań (ang. call stack), gdzie trafiają funkcje do wykonania.
Gdy jakaś funkcja wymaga więcej czasu (np. pobranie danych z serwera), JavaScript przekazuje ją do Web API (w przeglądarce) lub odpowiednich mechanizmów w Node.js.
Po zakończeniu tej operacji funkcja trafia do kolejki zdarzeń (ang. event queue), czekając na swoją kolej. Event Loop dba o to, by gdy call stack będzie pusty, wziąć funkcję z kolejki i ją wykonać.
Jak to działa w praktyce? 🛠️
Zobaczmy prosty przykład:
console.log("Start");
setTimeout(() => {
console.log("Cześć z setTimeout!");
}, 1000);
console.log("Koniec");
Rzobijmy ten przykład na konkretne etapy
- JavaScript wykonuje
console.log("Start")
– na ekranie pojawia się "Start". - Napotyka
setTimeout
z opóźnieniem 1000 ms. Funkcja callback jest przekazywana do Web API, a główny wątek idzie dalej. - Wykonuje
console.log("Koniec")
– wyświetla "Koniec". - Po 1000 ms Web API przekazuje funkcję callback do event queue.
- Event Loop sprawdza, że call stack jest pusty i przekazuje funkcję z kolejki do wykonania.
- Funkcja callback z
setTimeout
jest wykonywana – wyświetla "Cześć z setTimeout!".
W rezultacie na ekranie zobaczysz:
Start
Koniec
Cześć z setTimeout!
Dlaczego kolejność jest taka, a nie inna? 📅
To właśnie magia Event Loop.
Nawet jeśli ustawisz setTimeout
z opóźnieniem 0 ms, funkcja callback trafi do event queue i zostanie wykonana dopiero po zakończeniu bieżącego cyklu call stack.
Spójrz na ten przykład:
console.log("Start");
setTimeout(() => {
console.log("Zadanie z setTimeout");
}, 0);
console.log("Koniec");
Wynik będzie taki sam:
Start
Koniec
Zadanie z setTimeout
Mimo że opóźnienie to 0 ms, funkcja z setTimeout
zostanie wykonana po "Koniec".
źródło: https://medium.com/@piyushsingh0992/event-loop-in-javascript-c90663bb67
Promisy i mikro-kolejka zadań 🧐
Wprowadźmy do gry Promisy:
console.log("Start");
setTimeout(() => {
console.log("Zadanie z setTimeout");
}, 0);
Promise.resolve().then(() => {
console.log("Zadanie z Promisa");
});
console.log("Koniec");
Jaki będzie wynik?
Start
Koniec
Zadanie z Promisa
Zadanie z setTimeout
Dlaczego tak? Promisy trafiają do tzw. mikro-kolejki zadań (ang. microtask queue), która ma wyższy priorytet niż zwykła event queue.
Oznacza to, że zadania z mikro-kolejki zostaną wykonane przed tymi z event queue, jeśli call stack jest pusty.
Asynchroniczność w JavaScript 🚀
Dzięki Event Loop możemy korzystać z asynchroniczności w JavaScript bez problemów.
Funkcje takie jak setTimeout
, fetch
czy Promisy pozwalają na wykonywanie zadań w tle, nie blokując głównego wątku.
Event Loop w Node.js 🌐
W środowisku Node.js Event Loop działa podobnie, choć korzysta z innych mechanizmów niż przeglądarka.
Obsługuje operacje na plikach, żądania sieciowe i inne zadania I/O.
Dzięki temu Node.js może obsługiwać wiele połączeń jednocześnie, nie blokując głównego wątku.
Uważaj na blokowanie pętli zdarzeń ⚠️
Jeśli wykonasz ciężką operację synchroniczną, np. skomplikowane obliczenia, możesz zablokować Event Loop.
W efekcie aplikacja przestanie reagować na zdarzenia użytkownika. Dlatego ważne jest, by długotrwałe zadania wykonywać asynchronicznie lub w osobnych wątkach (np. za pomocą Web Workers).
Podsumowanie 🎉
Event Loop to serce asynchroniczności w JavaScript.
Dzięki niemu możemy tworzyć responsywne i wydajne aplikacje, które nie blokują się podczas wykonywania zadań w tle.
Zrozumienie tego mechanizmu jest must-have dla każdego programisty pracującego z JavaScript-em.
Jeśli spodobał Ci się ten artykuł, sprawdź inne wpisy na moim blogu. Do zobaczenia! 👋