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 ireject
dla niepowodzenia. setTimeout
jest używany do wywołaniaresolve()
po jednej sekundzie.- Metoda
then()
obiektupromise
oczekuje na zakończenie i wyświetla wynik.
- Najpierw tworzony jest nowy obiekt
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ą metodythen()
.
- Proces asynchroniczny zakończył się sukcesem, a wynik został zwrócony przez
- Odrzucone
- Proces asynchroniczny zakończył się niepowodzeniem i wystąpił błąd poprzez
reject()
. Błąd jest odbierany za pomocą metodycatch()
.
- Proces asynchroniczny zakończył się niepowodzeniem i wystąpił błąd poprzez
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, gdyPromise
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, gdyPromise
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, czyPromise
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 przezthen
jest przekazywana do następnegothen
. - 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 obiektPromise
, metodathen()
jest używana do przetworzenia danych po otrzymaniu odpowiedzi z serwera. Błędy są obsługiwane za pomocą metodycatch()
.
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 obiektyPromise
zakończą się sukcesem. Metodacatch()
jest wywoływana, jeśli chociaż jeden obiektPromise
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 obiektyPromise
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ącPromise.all()
lubPromise.race()
. async
/await
to składnia pozwalająca na prostsze pisanie obiektówPromise
.
Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.