Klasa Promise w JavaScript

Klasa Promise w JavaScript

W tym artykule wyjaśniamy klasę Promise w JavaScript.

YouTube Video

Promise

Klasa Promise jest klasą do obsługi operacji asynchronicznych. Obsługuje wyniki, jeśli operacja zakończy się powodzeniem, lub obsługę błędów, jeśli się nie powiedzie. Tradycyjnie używano funkcji zwrotnych (callback), gdy należało poczekać na zakończenie operacji asynchronicznej, ale Promise sprawia, że jest to jaśniejsze i bardziej efektywne.

1const promise = new Promise((resolve, reject) => {
2    setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
  • Ten kod jest przykładem procesu asynchronicznego, który wyświetla "Gotowe!" po jednej sekundzie.
    • Najpierw tworzony jest nowy obiekt Promise za pomocą new Promise. Argumentem jest funkcja przyjmująca dwa wywołania zwrotne: resolve dla sukcesu i reject dla niepowodzenia.
    • setTimeout jest używany do wywołania resolve() po jednej sekundzie.
    • Metoda then() obiektu promise oczekuje na zakończenie i wyświetla wynik.

Podstawowa struktura

Promise to obiekt, który ostatecznie kończy się sukcesem lub niepowodzeniem.

 1const promise = new Promise((resolve, reject) => {
 2    // Asynchronous operation
 3    // Flag indicating whether the operation was successful
 4    const success = true;
 5
 6    if (success) {
 7        resolve('Operation successful!');
 8    } else {
 9        reject('An error occurred');
10    }
11});
  • W przypadku sukcesu wywoływany jest resolve().
  • W przypadku niepowodzenia wywoływany jest reject().

Obiekt Promise może znajdować się w trzech stanach.

1promise
2    .then((result) => {
3        console.log(result);
4    })
5    .catch((error) => {
6        console.error(error);
7    })
  • Oczekujące
    • Proces asynchroniczny nie został jeszcze zakończony.
  • Spełnione
    • Proces asynchroniczny zakończył się sukcesem, a wynik został zwrócony przez resolve(). Wynik jest odbierany za pomocą metody then().
  • Odrzucone
    • Proces asynchroniczny zakończył się niepowodzeniem i wystąpił błąd poprzez reject(). Błąd jest odbierany za pomocą metody catch().

Metody then() oraz catch()

Za pomocą Promise możesz określić, co zrobić po zakończeniu operacji asynchronicznej. Do tego wykorzystujesz metody then() i catch().

then()

1const promise = new Promise((resolve, reject) => {
2    resolve('Operation successful!');
3});
4
5promise.then((result) => {
6    console.log(result);  // "Operation successful!"
7});
  • Metoda then() określa funkcję, która zostanie wywołana, gdy Promise zakończy się powodzeniem.

catch()

1const promise = new Promise((resolve, reject) => {
2    reject('An error occurred');
3});
4
5promise.catch((error) => {
6    console.error(error);  // "An error occurred"
7});
  • Metoda catch() określa funkcję, która zostanie wywołana, gdy Promise zakończy się błędem.

Metoda finally()

 1const promise = new Promise((resolve, reject) => {
 2    resolve('Operation successful!');
 3});
 4
 5promise
 6    .then((result) => {
 7        console.log(result);
 8    })
 9    .catch((error) => {
10        console.error(error);
11    })
12    .finally(() => {
13        console.log('The operation has completed');
14    });
  • Metoda finally() definiuje kod, który zostanie wykonany na końcu, niezależnie od tego, czy Promise zakończył się powodzeniem, czy błędem.

then() – łańcuch

then() zwraca nowy obiekt Promise, więc możesz łączyć kolejne wywołania then().

 1const promise = new Promise((resolve, reject) => {
 2    setTimeout(() => {
 3        resolve(1);
 4    }, 1000);
 5});
 6
 7promise
 8    .then(result => {
 9        console.log(result); // 1
10        return result + 1;
11    })
12    .then(result => {
13        console.log(result); // 2
14        return result + 1;
15    })
16    .then(result => {
17        console.log(result); // 3
18    })
19    .catch(error => {
20        console.error(error.message); // Something went wrong
21    });
  • W tym kodzie początkowe wywołanie resolve() przekazuje wartość 1, a każda wartość zwrócona przez then jest przekazywana do następnego then.
  • Używając catch(), możesz obsłużyć każdy błąd, który wystąpi w łańcuchu, w jednym miejscu.

Praktyczny przykład

Na przykład Promises są często używane do pobierania danych z serwera. Spójrzmy na przykład użycia API fetch().

 1fetch('https://codesparklab.com/json/example.json')
 2    .then(response => {
 3        if (!response.ok) {
 4            throw new Error('Network error');
 5        }
 6        return response.json();
 7    })
 8    .then(data => {
 9        console.log(data);
10    })
11    .catch(error => {
12        console.error('Error:', error);
13    });
  • W tym kodzie, ponieważ fetch() zwraca obiekt Promise, metoda then() jest używana do przetworzenia danych po otrzymaniu odpowiedzi z serwera. Błędy są obsługiwane za pomocą metody catch().

Obsługa wielu obiektów Promise

Promise.all()

Aby wykonać wiele obiektów Promise jednocześnie i kontynuować tylko wtedy, gdy wszystkie zakończą się sukcesem, użyj Promise.all().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • Metoda then() jest wywoływana tylko wtedy, gdy wszystkie obiekty Promise zakończą się sukcesem. Metoda catch() jest wywoływana, jeśli chociaż jeden obiekt Promise zakończy się niepowodzeniem.

Promise.allSettled()

Jeśli chcesz uruchomić wiele obietnic (Promise) jednocześnie i uzyskać wszystkie wyniki bez względu na sukces lub porażkę, użyj Promise.allSettled().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • then() jest wywoływany, gdy wszystkie obiekty Promise zostaną rozstrzygnięte (zrealizowane lub odrzucone). Każdy wynik zawiera właściwość status ('fulfilled' lub 'rejected'). Nawet jeśli niektóre się nie powiodą, nie ma to wpływu na pozostałe operacje.

Promise.race()

Promise.race() zwraca wynik tego Promise, który zakończy się jako pierwszy, niezależnie czy zostało spełnione, czy odrzucone.

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • Tak jak w tym przykładzie, zwracany jest wynik pierwszego zakończonego Promise.

Związek z async/await

Użycie składni async/await pozwala pisać obiekty Promise w bardziej intuicyjny sposób. Funkcja async zawsze zwraca obiekt Promise, a await czeka na jego zakończenie.

 1async function fetchData() {
 2    try {
 3        const response = await fetch('https://codesparklab.com/json/example.json');
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error('Error :', error);
 8    }
 9}
10
11fetchData();

Stosując async/await w ten sposób, operacje asynchroniczne można zapisywać jak kod synchroniczny, co ułatwia jego czytanie.

Podsumowanie

  • Promise to obiekt służący do obsługi sukcesu lub błędu operacji asynchronicznych.
  • Sukces operacji obsługuje się za pomocą metody then(), a błędy za pomocą catch().
  • finally() definiuje kod, który jest wykonywany na końcu, niezależnie od sukcesu lub błędu.
  • Możesz obsługiwać wiele obiektów Promise jednocześnie, używając Promise.all() lub Promise.race().
  • async/await to składnia pozwalająca na prostsze pisanie obiektów Promise.

Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.

YouTube Video