Async/await bez magii
Asynchroniczny JavaScript jest prostszy, gdy przestaniemy traktować async/await jak składniową sztuczkę i zobaczymy, co naprawdę robi.
async/await poprawił czytelność asynchronicznego JavaScriptu, ale nie usunął asynchroniczności. Kod nadal pracuje na obietnicach. Zmienił się sposób, w jaki go zapisujemy.
Funkcja async zawsze zwraca Promise
Nawet jeśli zwrócisz zwykłą liczbę, JavaScript opakuje ją w obietnicę.
async function answer() {
return 42;
}
answer().then(console.log); // 42
To ważne przy projektowaniu API. Wywołujący musi wynik odczekać albo obsłużyć przez .then().
Await nie blokuje całej aplikacji
await wstrzymuje tylko wykonanie bieżącej funkcji async. Pętla zdarzeń może w tym czasie obsługiwać inne zadania. Problem zaczyna się wtedy, gdy niezależne operacje uruchamiamy jedna po drugiej.
const user = await getUser();
const settings = await getSettings();
Jeśli te dane nie zależą od siebie, lepiej uruchomić oba żądania równolegle.
const [user, settings] = await Promise.all([
getUser(),
getSettings()
]);
Błędy muszą mieć właściciela
Najczęstszy błąd to await bez świadomej decyzji, gdzie wyjątek ma zostać obsłużony. Nie każda funkcja potrzebuje własnego try/catch. Czasem lepiej pozwolić, by błąd trafił poziom wyżej, do miejsca, które potrafi pokazać komunikat użytkownikowi albo ponowić operację.
Dobra zasada: łap błąd tam, gdzie możesz zrobić z nim coś sensownego. Samo console.log(error) zwykle nie jest obsługą.
Krótka lista kontrolna
- Czy niezależne operacje mogą działać równolegle?
- Czy wiadomo, kto obsługuje odrzuconą obietnicę?
- Czy użytkownik dostanie informację o błędzie?
- Czy operacja ma limit czasu albo możliwość anulowania?
Składnia jest prosta. Trudniejsze pozostaje myślenie o kolejności, błędach i czasie. I dobrze, bo właśnie tam dzieje się prawdziwa praca.