Async / await
Async/await to nowy sposób na zapis asynchronicznego kodu. Dzięki tym słowom praca z obietnicami zaczyna przypominać synchroniczny kod.
Async
Słowo async postawione przed dowolną funkcją tworzy z niej funkcję asynchroniczną, która zwraca obietnicę. Dzięki temu możemy później na nią reagować poznanymi w poprzednim rozdziale funkcjami:
function doThings() {
return Promise.resolve("ok");
}
doThings()
.then(res => {
console.log(res);
})
//to samo co
async function doThings() {
return "ok";
}
doThings()
.then(res => {
console.log(res); //"ok"
});Await
Słowo kluczowe await sprawia, że JavaScript poczeka na wykonanie asynchronicznego kodu. Dzięki temu zapis bardzo przypomina synchroniczny kod:
Słowa await możemy używać tylko wewnątrz funkcji poprzedzonej słowem async:
Niektórzy programiści wiedząc, że będą używać sporo asynchronicznych operacji wewnątrz swojego kodu, cały kod okrywają IIFE z async lub zdarzeniem DOMContentLoaded:
Przy czym w ES2022 zostanie to zmienione tak, byśmy mogli używać async w głównym kodzie - nawet poza funkcjami (pkt 3).
Obsługa błędów
W przypadku obsługi błędów za pomocą async/await, możemy posłużyć się konstrukcją try/catch, wewnątrz której spróbujemy wykonać jakieś operacje. Jeżeli one się nie powiodą przejmiemy komunikat błędu w sekcji catch:
Możemy też mieszać składnię async/await z then/catch:
Równoczesne operacje
Instrukcja await oznacza to, że kolejna operacja rozpocznie się dopiero, gdy poprzednia się zakończy.
W wielu momentach bardziej optymalnie będzie, gdy nasze operacje wywołamy równocześnie i poczekamy na ich zakończenie:
W przypadku zapisu za pomocą Promise kod mógłby wyglądać tak:
Mały przykład
Bardzo często omawiając asynchroniczność, pierwsze co nam przychodzi do głowy to pobieranie czy wysyłanie danych. Ale przecież operacje zajmujące jakiś czas wcale nie muszą wiązać się z przesyłaniem danych.
Podsumujmy ten rozdział mini przykładem. Mamy klasę, która tworzy i za pomocą setInterval animuje wykres:
Na jej bazie tworzymy pięć wykresów w jakimś testowym elemencie:
Po odpaleniu powyższego kodu dostaniemy 5 wykresów, które równocześnie zaczną się zapełniać.
Chcielibyśmy, by kolejne wykresy zaczęły się zapełniać jeden po drugim.
Funkcja animująca trwa jakiś czas, więc musimy jakoś zareagować na jej zakończenie.
Moglibyśmy więc jak w poprzednim rozdziale zrobić to za pomocą funkcji zwrotnej:
Wtedy reagowanie na zakończenie animacji zmusiło by nas do zagnieżdżania kolejnych wywołań.
Możemy więc pokusić się o zamianę funkcji animate() na obietnicę, dzięki czemu jej późniejsze użycie się uprości:
Ale możemy też połączyć to ze składnią async/await, co jeszcze bardziej uprości nasz kod:
Last updated