Promise

Obiekt reprezentujący wynik operacji, który pojawi się w przyszłości: wartość przy sukcesie albo błąd.

Zwraca
Nowy obiekt Promise w stanie oczekiwania.
Na tej stronie

Przykład

#
JavaScript
const promise = new Promise((resolve) => {
  console.log('1. Executor startuje od razu')
  setTimeout(() => resolve('3. Wynik po 300 ms'), 300)
})

promise.then((value) => console.log(value))
console.log('2. Kod po utworzeniu obietnicy')
Konsola
1. Executor startuje od razu
2. Kod po utworzeniu obietnicy
3. Wynik po 300 ms

Definicja i zastosowanie

#

Obietnica (Promise) to obiekt, który zastępuje wynik jeszcze niegotowej operacji, na przykład pobierania danych z serwera. Na początku jest w stanie oczekiwania (pending), a potem na stałe przechodzi w jeden z dwóch stanów: spełniona (fulfilled) z wartością albo odrzucona (rejected) z powodem błędu.

Konstruktor new Promise(executor) przyjmuje funkcję, która dostaje dwie inne funkcje: resolve do zgłoszenia sukcesu i reject do zgłoszenia błędu. Funkcja executor uruchamia się od razu, synchronicznie, w chwili tworzenia obietnicy. Na wynik reagujesz metodami then(), catch() i finally() albo słowem await.

Obietnica rozstrzyga się tylko raz. Kolejne wywołania resolve lub reject są ignorowane. Funkcje przekazane do then() zawsze wykonują się asynchronicznie, nawet gdy obietnica jest już spełniona, więc kod zapisany po nich wykona się wcześniej.

W praktyce rzadko tworzysz obietnice ręcznie. Zwracają je gotowe API, takie jak fetch(), oraz każda funkcja async. Konstruktor przydaje się głównie do opakowania starszego kodu opartego na funkcjach zwrotnych, na przykład setTimeout().

Składnia

#
Składnia
new Promise((resolve, reject) => { … })

Parametry

#
  • executor

    function (resolve, reject)

    Funkcja uruchamiana od razu przy tworzeniu obietnicy. Wywołaj w niej resolve(wartość) przy sukcesie albo reject(błąd) przy niepowodzeniu.

Więcej przykładów

#
Sukces i błąd
JavaScript
const checkAnswer = (answer) =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      if (answer === 42) resolve('Poprawna odpowiedź!')
      else reject(new Error('Spróbuj jeszcze raz'))
    }, 200)
  })

console.log('Sprawdzam...')
checkAnswer(42).then((message) => console.log(message))
checkAnswer(7).catch((error) => console.log(error.message))
Konsola
Sprawdzam...
Poprawna odpowiedź!
Spróbuj jeszcze raz
Opakowanie setTimeout() w obietnicę
JavaScript
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

console.log('Ładowanie poziomu...')
await wait(500)
console.log('Poziom załadowany')
Konsola
Ładowanie poziomu...
Poziom załadowany
Obietnica rozstrzyga się tylko raz
JavaScript
const promise = new Promise((resolve, reject) => {
  resolve('pierwszy wynik')
  resolve('drugi wynik')
  reject(new Error('za późno'))
})

promise.then((value) => console.log(value))
Konsola
pierwszy wynik

Obsługa przeglądarek

#

Szeroko dostępne

Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.

  • Chrome
  • Edge
  • Firefox
  • Safari

Dobre praktyki

#
  • Zawsze obsłuż błąd obietnicy przez catch() albo try...catch z await. Nieobsłużone odrzucenie pojawi się w konsoli jako błąd „Uncaught (in promise)”.
  • Do reject() przekazuj obiekt Error, a nie sam napis. Dostaniesz wtedy komunikat w message, nazwę błędu i stos wywołań.
  • Zamiast długich łańcuchów then() w nowym kodzie zwykle czytelniejsze jest async i await.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.