4.1 Słowo kluczowe async
Funkcje asynchroniczne w JavaScript pozwalają pisać kod asynchroniczny, który wygląda i czyta się jak synchroniczny.
Słowa kluczowe async
i await
, wprowadzone w ECMAScript 2017 (ES8), ułatwiają pracę z promesami
i sprawiają, że kod jest bardziej zrozumiały i zarządzalny.
Podstawowe koncepcje
Słowo kluczowe async
przed deklaracją funkcji wskazuje, że funkcja jest asynchroniczna. Funkcja asynchroniczna
zawsze zwraca promesę, nawet jeśli nie ma w niej jawnego operatora return
.
Jeśli funkcja zwraca wartość, jest ona automatycznie opakowana w promesę z tą wartością.
Składnia:
async function nazwa() {
// kod funkcji
}
Przykład:
async function greet() {
return 'Hello, world!';
}
greet().then((message) => {
console.log(message); // Wyświetli: Hello, world!
});
4.2 Słowo kluczowe await
Słowo kluczowe await
używane jest wewnątrz funkcji asynchronicznej do wstrzymania jej wykonywania do momentu, aż promesa
zostanie spełniona. await
można używać tylko wewnątrz funkcji zadeklarowanych ze słowem kluczowym async
.
Składnia:
let resultat = await
promise;
Przykład:
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function greet() {
await delay(2000);
return 'Hello, world!';
}
async function displayGreeting() {
const message = await greet();
console.log(message); // Wyświetli: Hello, world! po 2 sekundach
}
displayGreeting();
4.3 Przykłady użycia async i await
Przykład 1: Funkcja asynchroniczna czekająca na kilka promes
function fetchData1() {
return new Promise((resolve) => setTimeout(() => resolve('Data 1'), 1000));
}
function fetchData2() {
return new Promise((resolve) => setTimeout(() => resolve('Data 2'), 2000));
}
async function fetchAllData() {
const data1 = await fetchData1();
console.log(data1); // Wyświetli: Data 1 po 1 sekundzie
const data2 = await fetchData2();
console.log(data2); // Wyświetli: Data 2 po 2 sekundach
}
fetchAllData();
Przykład 2: Równoległe wykonywanie operacji asynchronicznych
Aby wykonać kilka operacji asynchronicznych równolegle, można użyć Promise.all()
z await
.
function fetchData1() {
return new Promise((resolve) => setTimeout(() => resolve('Data 1'), 1000));
}
function fetchData2() {
return new Promise((resolve) => setTimeout(() => resolve('Data 2'), 2000));
}
async function fetchAllData() {
const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
console.log(data1); // Wyświetli: Data 1 po 2 sekundach
console.log(data2); // Wyświetli: Data 2 po 2 sekundach
}
fetchAllData();
Przykład 3: Obsługa błędów za pomocą try...catch
Funkcje asynchroniczne pozwalają na użycie bloków try...catch
do obsługi błędów, co sprawia, że kod jest bardziej czytelny i zarządzalny.
function fetchDataWithError() {
return new Promise((resolve, reject) => setTimeout(() => reject('Error occurred'), 1000));
}
async function fetchData() {
try {
const data = await fetchDataWithError();
console.log(data);
} catch (error) {
console.error('Error:', error); // Wyświetli: Error: Error occurred po 1 sekundzie
}
}
fetchData();
Przykład 4: Użycie async i await w metodach klasy
Funkcje asynchroniczne można również używać w metodach klas.
class DataFetcher {
async fetchData() {
const data = await new Promise((resolve) => setTimeout(() => resolve('Fetched Data'), 1000));
return data;
}
}
const fetcher = new DataFetcher();
fetcher.fetchData().then((data) => {
console.log(data); // Wyświetli: Fetched Data po 1 sekundzie
});
Przykład 5: Asynchroniczne iteratory
Asynchroniczne iteratory pozwalają pracować ze strumieniami danych, które przychodzą asynchronicznie.
async function* asyncGenerator() {
let i = 0;
while (i < 3) {
await new Promise((resolve) => setTimeout(resolve, 1000));
yield i++;
}
}
async function iterateAsyncGenerator() {
for await (let value of asyncGenerator()) {
console.log(value); // Wyświetli 0, 1 i 2 z interwałem 1 sekundy
}
}
iterateAsyncGenerator();
GO TO FULL VERSION