0Pricing
Frontend Academy · Lekcja

async/await i obsługa błędów

Proszę pisać funkcje async ze słowem kluczowym await, opakowywać wywołania z await w bloki try/catch oraz zrozumieć, że async/await to cukier składniowy nad Promises.

async/await i obsługa błędów to bezpłatna lekcja Frontend Academy na CoddyKit. To lekcja 4 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.

Czym jest async/await?

async/await to cukier składniowy dla Promises. Funkcja async zawsze zwraca Promise. Słowo kluczowe await wstrzymuje funkcję do momentu ustalenia stanu oczekiwanego Promise. Kod wygląda synchronicznie, ale wykonuje się asynchronicznie.

Funkcja async

Należy dodać słowo kluczowe async przed deklaracją lub wyrażeniem funkcji. Funkcja będzie teraz niejawnie opakowywać zwracaną wartość w Promise.

async function fetchUser(id) {
  // implicitly returns a Promise
  return { id, name: 'Alice' };
}

// Equivalent to:
function fetchUser(id) {
  return Promise.resolve({ id, name: 'Alice' });
}

await — oczekiwanie na Promises

await można stosować tylko wewnątrz funkcji async. Wstrzymuje ono wykonywanie do momentu rozstrzygnięcia Promise i zwraca rozstrzygniętą wartość. Inny kod w pętli zdarzeń nadal działa.

async function loadProfile(id) {
  const user = await fetchUser(id);     // waits for Promise
  const posts = await fetchPosts(user.id); // waits again
  return { user, posts };
}

Sekwencyjne i równoległe użycie await

Sekwencyjne oczekiwanie jest łatwe do odczytania, ale powolne, jeśli zadania nie zależą od siebie. Należy użyć Promise.all(), aby oczekiwać równolegle na wiele niezależnych zadań.

// Sequential (slow if tasks are independent):
const user = await fetchUser(id);
const settings = await fetchSettings(id); // waits for user unnecessarily

// Parallel (fast):
const [user, settings] = await Promise.all([
  fetchUser(id),
  fetchSettings(id),
]);

try/catch do obsługi błędów

Należy umieszczać wywołania z await wewnątrz try/catch, aby obsługiwać odrzucenia. Blok catch otrzymuje powód odrzucenia jako obiekt błędu.

async function saveUser(data) {
  try {
    const response = await fetch('/api/users', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: { 'Content-Type': 'application/json' }
    });
    if (!response.ok) throw new Error(`Server error ${response.status}`);
    return await response.json();
  } catch (err) {
    console.error('Save failed:', err.message);
    throw err; // re-throw so caller can handle
  }
}

await na najwyższym poziomie

W modułach ES (a nie w CommonJS) można używać await na najwyższym poziomie bez opakowywania kodu w funkcję async. Jest to przydatne podczas inicjalizacji modułu.

// module.js (ES module)
const config = await fetch('/config.json').then(r => r.json());
export const API_URL = config.apiUrl;

async/await z forEach — pułapka

Array.forEach() nie oczekuje na asynchroniczne funkcje zwrotne. Do sekwencyjnej iteracji asynchronicznej należy użyć for...of, a do równoległej — Promise.all(arr.map(...)).

// WRONG — forEach doesn't await:
items.forEach(async (item) => {
  await processItem(item); // runs but forEach doesn't wait
});

// CORRECT — sequential:
for (const item of items) {
  await processItem(item);
}

// CORRECT — parallel:
await Promise.all(items.map(item => processItem(item)));

Obiekty błędów i błędy niestandardowe

Należy zawsze zgłaszać obiekty Error, a nie ciągi znaków, aby zachować ślady stosu. Dla błędów specyficznych dla domeny należy tworzyć niestandardowe klasy błędów, które wywołujący może przechwytywać na podstawie typu.

class NetworkError extends Error {
  constructor(message, status) {
    super(message);
    this.name = 'NetworkError';
    this.status = status;
  }
}

try {
  const res = await fetch(url);
  if (!res.ok) throw new NetworkError(`Failed`, res.status);
} catch (err) {
  if (err instanceof NetworkError && err.status === 401) {
    redirectToLogin();
  } else {
    throw err;
  }
}

finally w async/await

Blok finally wykonuje się niezależnie od tego, czy blok try zakończył się powodzeniem, czy błędem — podobnie jak .finally() dla Promise. Należy używać go do zwalniania zasobów lub ukrywania stanów ładowania.

async function loadData() {
  setLoading(true);
  try {
    const data = await fetch('/api/data').then(r => r.json());
    setData(data);
  } catch (err) {
    setError(err.message);
  } finally {
    setLoading(false); // always runs
  }
}

Asynchroniczne IIFE dla punktów wejścia modułów

Należy opakować punkt wejścia skryptu w asynchroniczne IIFE, gdy nie można użyć await na najwyższym poziomie.

(async () => {
  const data = await fetchInitialData();
  renderApp(data);
})();

AbortController do anulowania

Należy przekazać sygnał AbortController do fetch, aby anulować trwające żądanie. Oddzielne przechwycenie AbortError zapobiega wyświetleniu użytkownikowi komunikatu o błędzie.

const controller = new AbortController();

try {
  const data = await fetch(url, { signal: controller.signal }).then(r => r.json());
  setData(data);
} catch (err) {
  if (err.name !== 'AbortError') setError(err.message);
}

// Cancel:
controller.abort();

Szybkie sprawdzenie

Która konstrukcja prawidłowo obsługuje błędy z oczekiwanego Promise?

Podsumowanie: async/await

Funkcje async zawsze zwracają Promises. await wstrzymuje wykonywanie do momentu ustalenia stanu Promise. Do obsługi błędów należy używać try/catch. W przypadku operacji równoległych należy używać Promise.all(). Należy unikać await wewnątrz forEach — zamiast tego używać for...of lub Promise.all. AbortController anuluje trwające żądania. await na najwyższym poziomie działa w modułach ES.

Często zadawane pytania

Czy lekcja „async/await i obsługa błędów” jest bezpłatna?

Tak — pełny tekst „async/await i obsługa błędów” 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 „async/await i obsługa błędów”?

Proszę pisać funkcje async ze słowem kluczowym await, opakowywać wywołania z await w bloki try/catch oraz zrozumieć, że async/await to cukier składniowy nad Promises. Ć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 4 z 4.

Ile czasu zajmuje lekcja „async/await i obsługa błędów”?

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

  1. Pętla zdarzeń: call stack, kolejka, mikrozadania
  2. Callbacki i callback hell
  3. Promises: then, catch, finally, Promise.all
  4. async/await i obsługa błędów
← Powrót do Frontend Academy