Node.js dla początkujących - Część 10: Asynchroniczność

1/16/2025 Kurs JavaScript

Mateusz Kędziora

image

Witajcie w dziesiątej części naszego kursu JavaScript! Dziś zmierzymy się z tematem, który na początku może wydawać się nieco skomplikowany, ale jest absolutnie kluczowy dla każdego programisty JavaScript – asynchronicznością. Obiecuję, że po przeczytaniu tego artykułu, zrozumiecie, o co w tym wszystkim chodzi.

Czym jest asynchroniczność?

Wyobraźcie sobie, że jesteście w restauracji. Składacie zamówienie i czekacie, aż kucharz je przygotuje. W „synchronicznym” świecie, musielibyście stać bezczynnie i patrzeć, jak kucharz gotuje, blokując sobie możliwość robienia czegokolwiek innego. W „asynchronicznym” świecie, po złożeniu zamówienia, możecie wrócić do stolika, porozmawiać ze znajomymi, poczytać książkę, a kelner przyniesie Wam posiłek, gdy będzie gotowy.

W JavaScript, asynchroniczność pozwala nam na wykonywanie operacji, które trwają pewien czas (np. pobieranie danych z serwera), bez blokowania głównego wątku programu. Dzięki temu nasza strona internetowa nie „zawiesza się”, a użytkownik może swobodnie z niej korzystać.

Callbacki – Pierwszy krok

Najstarszym sposobem obsługi asynchroniczności w JavaScript są callbacki. Callback to po prostu funkcja, która jest przekazywana jako argument do innej funkcji i wywoływana po zakończeniu pewnej operacji.

function pobierzDane(callback) {
  setTimeout(() => {
    const dane = "Dane z serwera";
    callback(dane); // Wywołujemy callback z danymi
  }, 2000); // Symulujemy opóźnienie 2 sekundy
}

function wyswietlDane(dane) {
  console.log("Otrzymane dane: " + dane);
}

pobierzDane(wyswietlDane); // Przekazujemy funkcję wyswietlDane jako callback
console.log("Czekam na dane...");

W tym przykładzie, wyswietlDane jest callbackiem. Zostanie wywołany dopiero po 2 sekundach, gdy pobierzDane „skończy pracę”. Ja rozumiem, że na początku callbacki mogą wydawać się nieco dziwne, ale z czasem się do nich przyzwyczaicie.

Obietnice (Promises)

Obietnice (Promises) to nowocześniejsze podejście do asynchroniczności. Obietnica reprezentuje wynik operacji asynchronicznej, który może być w jednym z trzech stanów:

  • pending (oczekujący) – operacja jeszcze się nie zakończyła.
  • fulfilled (spełniony) – operacja zakończyła się sukcesem.
  • rejected (odrzucony) – operacja zakończyła się błędem.
function pobierzDane() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const dane = "Dane z serwera (z Promise)";
      resolve(dane); // Rozwiązujemy obietnicę z danymi
      // reject("Błąd pobierania danych"); // Odrzucamy obietnicę w przypadku błędu
    }, 2000);
  });
}

pobierzDane()
  .then(dane => { // Obsługujemy sukces
    console.log("Otrzymane dane: " + dane);
  })
  .catch(error => { // Obsługujemy błąd
    console.error("Wystąpił błąd: " + error);
  });
console.log("Czekam na dane...");

Uważam, że Promises są znacznie czytelniejsze i łatwiejsze w użyciu niż callbacki, zwłaszcza przy bardziej złożonych operacjach asynchronicznych.

Async/await

Async/await to jeszcze inne podejście, które sprawia, że kod asynchroniczny wygląda i zachowuje się jak synchroniczny. Aby użyć async/await, musimy oznaczyć funkcję jako async, a następnie użyć słowa kluczowego await przed wywołaniem funkcji zwracającej Promise.

async function pobierzIDane() {
    try{
        const dane = await pobierzDane(); // Czekamy na rozwiązanie obietnicy
        console.log("Otrzymane dane z async/await: " + dane);
    } catch (error) {
        console.error("Wystąpił błąd: " + error);
    }
}
pobierzIDane();
console.log("Czekam na dane...");

Dla mnie async/await jest najwygodniejszym sposobem pracy z asynchronicznością. Kod jest czysty, czytelny i łatwy do zrozumienia.

Podsumowanie

Nauczyliśmy się dzisiaj, jak radzić sobie z asynchronicznością w JavaScript za pomocą callbacków, Promises i async/await. Zachęcam Was do eksperymentowania z tymi technikami i samodzielnego pisania kodu.

Praca domowa

  1. Napisz funkcję, która pobiera dane z losowego API (np. https://catfact.ninja/fact - losowy fakt o kotach) za pomocą fetch i wyświetla je na stronie. Użyj Promises i async/await.
  2. Stwórz funkcję, która pobiera dane z dwóch różnych API jednocześnie i wyświetla wyniki po pobraniu danych z obu źródeł.

Pamiętajcie, że praktyka czyni mistrza! Eksperymentujcie, czytajcie dokumentację i nie bójcie się zadawać pytań. Ja wierzę w Wasz sukces! Zachęcam również do przeczytania pozostałych postów z naszego kursu, gdzie znajdziecie mnóstwo przydatnych informacji. Do zobaczenia w kolejnej części!

Polecane artykuły