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 orderPromise.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 sequentialPromise.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)); // 42Zdarzenia 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
- Pętla zdarzeń: call stack, kolejka, mikrozadania
- Callbacki i callback hell
- Promises: then, catch, finally, Promise.all
- async/await i obsługa błędów