0Pricing
Frontend Academy · Lekcja

Promises: then, catch, finally, Promise.all

Proszę tworzyć i łączyć Promises, obsługiwać błędy w blokach catch, wykonywać sprzątanie w finally oraz uruchamiać wiele Promises równolegle za pomocą Promise.all.

Promises: then, catch, finally, Promise.all to bezpłatna lekcja Frontend Academy na CoddyKit. To lekcja 3 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 Promise?

Promise reprezentuje wartość, która będzie dostępna w przyszłości. Jest obiektem znajdującym się w jednym z trzech stanów: pending (początkowy), fulfilled (spełniony wartością) lub rejected (odrzucony z określonego powodu). Po ustaleniu stan Promise jest niezmienny.

Tworzenie Promise

Promise tworzy się za pomocą konstruktora new Promise(executor). Funkcja wykonawcza otrzymuje funkcje zwrotne resolve i reject. Należy wywołać resolve z wartością oznaczającą powodzenie albo reject z błędem.

const delay = (ms) => new Promise((resolve) => {
  setTimeout(resolve, ms);
});

const fetchData = (url) => new Promise((resolve, reject) => {
  fetch(url)
    .then(res => res.json())
    .then(resolve)
    .catch(reject);
});

.then() — obsługa powodzenia

promise.then(onFulfilled) rejestruje funkcję zwrotną wykonywaną po spełnieniu Promise. Otrzymuje ona rozstrzygniętą wartość. .then() zwraca nowy Promise, co umożliwia tworzenie łańcuchów.

fetch('/api/users')
  .then(response => response.json())
  .then(users => {
    console.log('Users:', users);
    return users.length;
  })
  .then(count => console.log('Count:', count));

.catch() — obsługa błędów

promise.catch(onRejected) obsługuje odrzucenia. Umieszczony na końcu łańcucha przechwytuje każdy błąd z dowolnego wcześniejszego kroku.

fetch('/api/data')
  .then(res => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .then(data => processData(data))
  .catch(err => {
    console.error('Failed:', err.message);
    showErrorToUser();
  });

.finally() — wykonywanie w każdym przypadku

promise.finally(onFinally) wykonuje się niezależnie od tego, czy Promise został spełniony, czy odrzucony. Doskonale nadaje się do sprzątania: ukrywania wskaźnika ładowania, zwalniania blokady i rejestrowania danych analitycznych.

showSpinner();
fetch('/api/data')
  .then(res => res.json())
  .then(render)
  .catch(handleError)
  .finally(() => hideSpinner()); // always runs

Łączenie Promise — zwracanie wartości

Zwrócenie wartości z .then() sprawia, że staje się ona rozstrzygniętą wartością następnego .then(). Zwrócenie nowego Promise umożliwia sekwencyjne łączenie operacji asynchronicznych.

getUser(id)
  .then(user => getOrders(user.id))  // return Promise
  .then(orders => orders[0])          // return value
  .then(order => console.log(order)); // receive order

Promise.all() — wykonywanie równoległe

Promise.all([p1, p2, p3]) czeka na rozstrzygnięcie wszystkich promises i zwraca tablicę wyników w tej samej kolejności. Jeśli dowolny Promise zostanie odrzucony, całość zostaje natychmiast odrzucona.

const [user, posts, comments] = await Promise.all([
  fetch('/api/user/1').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
  fetch('/api/comments').then(r => r.json()),
]);
// All three run in parallel — much faster than sequential

Promise.allSettled() — bez natychmiastowego niepowodzenia

Promise.allSettled() czeka, aż wszystkie promises ustalą stan (zostaną spełnione lub odrzucone), i zwraca tablicę obiektów wyników zawierających {status, value} lub {status, reason}. Jest przydatne, gdy pojedyncze niepowodzenie nie powinno przekreślać wszystkich wyników.

const results = await Promise.allSettled([p1, p2, p3]);
results.forEach(result => {
  if (result.status === 'fulfilled') use(result.value);
  else logError(result.reason);
});

Promise.race() i Promise.any()

Promise.race() rozstrzyga się lub odrzuca zgodnie z pierwszym Promise, który ustali stan. Promise.any() rozstrzyga się za pomocą pierwszego spełnionego Promise (ignoruje odrzucenia; odrzuca się tylko wtedy, gdy wszystkie promises zostaną odrzucone). Przydatne w przypadku limitów czasu i redundancji.

// Timeout pattern:
const withTimeout = (promise, ms) => Promise.race([
  promise,
  new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms))
]);

Tworzenie już rozstrzygniętych promises

Promise.resolve(value) tworzy Promise już spełniony wartością value. Promise.reject(error) tworzy już odrzucony Promise. Jest to przydatne podczas testowania i tworzenia funkcji adapterów.

const p = Promise.resolve(42);
p.then(v => console.log(v)); // 42

Zdarzenia nieobsłużonych odrzuceń

Jeśli Promise zostanie odrzucony bez .catch(), staje się nieobsłużonym odrzuceniem. Współczesne przeglądarki i Node.js wyświetlają ostrzeżenia. Należy zawsze dołączać .catch() albo używać try/catch wraz z async/await.

window.addEventListener('unhandledrejection', event => {
  console.error('Unhandled rejection:', event.reason);
  event.preventDefault();
});

Szybkie sprawdzenie

Która metoda statyczna uruchamia wiele promises równolegle i rozstrzyga się tablicą wszystkich wyników?

Podsumowanie: Promises

.then() służy do obsługi powodzenia, .catch() do obsługi błędów, a .finally() do sprzątania. Łańcuchy przekazują wartości dalej. Promise.all() wykonuje operacje równolegle. Promise.allSettled() toleruje częściowe niepowodzenia. Promise.race() służy do uzyskania najszybszego wyniku. Należy zawsze obsługiwać odrzucenia. Współczesny kod używa async/await jako cukru składniowego dla Promises.

Często zadawane pytania

Czy lekcja „Promises: then, catch, finally, Promise.all” jest bezpłatna?

Tak — pełny tekst „Promises: then, catch, finally, Promise.all” 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 „Promises: then, catch, finally, Promise.all”?

Proszę tworzyć i łączyć Promises, obsługiwać błędy w blokach catch, wykonywać sprzątanie w finally oraz uruchamiać wiele Promises równolegle za pomocą Promise.all. Ć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 3 z 4.

Ile czasu zajmuje lekcja „Promises: then, catch, finally, Promise.all”?

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