Async/await w JavaScript
W tym artykule wyjaśnimy async/await w JavaScript.
YouTube Video
Async/await w JavaScript
async (i await) w JavaScript to funkcje zaprojektowane, aby pisanie operacji asynchronicznych było bardziej intuicyjne i czytelne. Korzystając z tego, możesz zmniejszyć złożoność tradycyjnych funkcji zwrotnych i łańcuchów Promise, a kod asynchroniczny pisać w sposób przypominający kod synchroniczny.
Funkcja async
async jest używane do zdefiniowania funkcji jako funkcji asynchronicznej. Funkcja async zawsze zwraca obietnicę (Promise). W funkcji oznaczonej jako async można użyć await, aby poczekać na zwrócenie wyniku obietnicy (Promise).
Podstawowa składnia funkcji async
1async function myAsyncFunction() {
2 // Write asynchronous processing here
3 return 'Result'; // Return a Promise
4}W tym przypadku wywołanie myAsyncFunction() automatycznie zwraca obiekt Promise. Po rozwiązaniu obietnicy (Promise) jej wynik staje się wartością zwracaną przez return.
Przykład: Podstawowa funkcja async
1async function greet() {
2 return 'Hello, World!';
3}
4
5greet().then((message) => {
6 console.log(message); // Displays "Hello, World!"
7});await
await jest używane, aby zaczekać na rozwiązanie obietnicy (Promise). Korzystając z await, możesz wstrzymać wykonywanie kodu, aż obietnica (Promise) zostanie rozwiązana, i odebrać jej wynik. await może być używane tylko wewnątrz funkcji async.
Przykład: Jak używać await
1async function fetchData() {
2 // Wait for the result of the Promise
3 const data = await fetch('https://codesparklab.com/json/example.json');
4 // Wait for the asynchronous operation to complete
5 const jsonData = await data.json();
6 // Retrieve and display the data
7 console.log(jsonData);
8}
9
10fetchData();W powyższym przykładzie oczekuje na obietnicę (Promise) zwróconą przez funkcję fetch za pomocą await, a następnie wykonuje dalsze operacje asynchroniczne, używając wyniku.
Obsługa błędów z użyciem async/await
Jeśli wewnątrz funkcji async wystąpi błąd, błąd ten jest traktowany jako reject obietnicy (Promise). Możesz użyć instrukcji try...catch, aby obsługiwać błędy.
Przykład: Obsługa błędów
1async function fetchData() {
2 try {
3 // Invalid URL
4 const data = await fetch('https://invalid.codesparklab.com/');
5 const jsonData = await data.json();
6 console.log(jsonData);
7 } catch (error) {
8 // Catch the error
9 console.error('Failed to fetch data:', error);
10 }
11}
12
13fetchData();Użycie bloku try...catch pozwala wychwytywać błędy występujące podczas operacji asynchronicznych, zapobiegając awarii programu w przypadku wystąpienia błędów.
Zalety async/await
W porównaniu do tradycyjnych łańcuchów Promise, async/await oferuje następujące zalety:.
- Poprawiona czytelność
- Przetwarzanie asynchroniczne można pisać jak kod synchroniczny, unikając złożoności głęboko zagnieżdżonych łańcuchów
Promisei funkcji zwrotnych.
- Przetwarzanie asynchroniczne można pisać jak kod synchroniczny, unikając złożoności głęboko zagnieżdżonych łańcuchów
- Łatwiejsze debugowanie
- Ponieważ kod wygląda jak synchroniczny, debugowanie i obsługa błędów są łatwiejsze.
- Lepsza konserwowalność
- Procesy asynchroniczne można pisać prościej, co ułatwia wprowadzanie zmian lub modyfikowanie kodu oraz poprawia długoterminową konserwowalność.
Przykład: łańcuch Promise vs async/await
Porównajmy kod wykorzystujący łańcuchy Promise oraz kod z użyciem async/await.
1// Code using Promise chains
2function fetchDataPromise() {
3 fetch('https://codesparklab.com/json/example.json')
4 .then((response) => response.json())
5 .then((data) => {
6 console.log(data);
7 })
8 .catch((error) => {
9 console.error('Failed to fetch data:', error);
10 });
11}
12
13// Code using async/await
14async function fetchDataAsync() {
15 try {
16 const response = await fetch('https://codesparklab.com/json/example.json');
17 const data = await response.json();
18 console.log(data);
19 } catch (error) {
20 console.error('Failed to fetch data:', error);
21 }
22}Jak widać, użycie async/await pozwala pisać procesy asynchroniczne w sposób liniowy, co skutkuje bardziej czytelnym kodem.
Wykonywanie wielu operacji asynchronicznych jednocześnie
Łącząc Promise.all() lub Promise.race() z await, możesz wykonywać wiele operacji asynchronicznych jednocześnie i zbiorczo obsługiwać ich wyniki.
Promise.all()
1async function fetchMultipleData() {
2 try {
3 const [data1, data2] = await Promise.all([
4 fetch('https://codesparklab.com/json/example1.json'),
5 fetch('https://codesparklab.com/json/example2.json')
6 ]);
7 const jsonData1 = await data1.json();
8 const jsonData2 = await data2.json();
9 console.log(jsonData1);
10 console.log(jsonData2);
11 } catch (error) {
12 console.error('Failed to fetch data:', error);
13 }
14}
15
16fetchMultipleData();Promise.all()rozwiązuje wiele obietnic (Promise) jednocześnie i zwraca ich wyniki w postaci tablicy. Czeka, aż wszystkie obietnice (Promise) zostaną rozwiązane, a jeśli którakolwiek z nich się nie powiedzie, cały proces jest uznawany za niepowodzenie.
Promise.race()
1async function fetchFastestData() {
2 try {
3 const fastestResponse = await Promise.race([
4 fetch('https://codesparklab.com/json/example1.json'),
5 fetch('https://codesparklab.com/json/example2.json')
6 ]);
7 const jsonData = await fastestResponse.json();
8 console.log('Fastest data:', jsonData);
9 } catch (error) {
10 console.error('Fetch error:', error);
11 }
12}
13
14fetchFastestData();Promise.race()zwraca wynik pierwszej obietnicy (Promise), która zostanie spełniona lub odrzucona. Jest to przydatne, gdy chcesz zareagować na tę operację asynchroniczną, która zakończy się jako pierwsza. Jednak jeśli pierwsza obietnica (Promise) zakończy się niepowodzeniem, błąd zostanie natychmiast przechwycony przezcatch.
Promise.allSettled()
1async function fetchWithAllSettled() {
2 const results = await Promise.allSettled([
3 // This URL will success
4 fetch('https://codesparklab.com/json/example1.json'),
5 // This URL will fail
6 fetch('https://invalid.codesparklab.com/')
7 ]);
8
9 results.forEach((result, index) => {
10 if (result.status === 'fulfilled') {
11 const url = result.value.url;
12 console.log(`Request ${index + 1} succeeded:`, url);
13 } else {
14 const reason = result.reason;
15 console.warn(`Request ${index + 1} failed:`, reason);
16 }
17 });
18}
19
20fetchWithAllSettled();Promise.allSettled()czeka na wszystkie wyniki, niezależnie od tego, czy zakończyły się powodzeniem, czy niepowodzeniem. Każdy wynik jest zwracany w postaci{ status, value }lub{ status, reason }, co pozwala określić, które obietnice (Promise) zakończyły się powodzeniem, a które niepowodzeniem.
Promise.any()
1async function fetchAnySuccessful() {
2 try {
3 const firstSuccessful = await Promise.any([
4 // This URL will fail
5 fetch('https://invalid.codesparklab.com/'),
6 // This URL will success
7 fetch('https://codesparklab.com/json/example1.json')
8 ]);
9 const jsonData = await firstSuccessful.json();
10 console.log('First successful response:', jsonData);
11 } catch (error) {
12 console.error('All fetch requests failed:', error);
13 }
14}
15
16fetchAnySuccessful();Promise.any()zwraca tylko wynik pierwszej pomyślnie spełnionej obietnicy (Promise). Wyjątek jest zgłaszany tylko wtedy, gdy wszystkie obietnice (Promise) zakończą się niepowodzeniem. Można tego użyć jako mechanizmu ponawiania prób w środowiskach, gdzie niektóre API są zawodne, dopóki jedna z nich się nie powiedzie.
Podsumowanie
- Funkcja
async: Zawsze zwraca Promise i jest używana do pisania przetwarzania asynchronicznego. await: Używane do oczekiwania na rozwiązanie Promise i pobranie jego wyniku.- Obsługa błędów: Używaj
try...catchdo obsługi błędów, które występują podczas przetwarzania asynchronicznego. - Wiele operacji asynchronicznych: Używając metod takich jak
Promise.all(), możesz wykonywać wiele zadań asynchronicznych jednocześnie.
async/await to potężne narzędzia do obsługi przetwarzania asynchronicznego, dlatego warto z nich korzystać, aby uprościć złożoną logikę asynchroniczną.
Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.