Maybaygiare.org

Blog Network

obsługa błędów w długich łańcuchach obietnic

Tao obietnic

mając trochę więcej doświadczenia i zrozumienia obietnic i monadycznych praw, które regulują ich użycie, nie spędzilibyśmy tyle czasu na pracy nad refaktoringiem tego fragmentu kodu.

w JavaScript, kod asynchroniczny może być obsługiwany przez Promises, które są kontynuacją Monad JavaScript. Najważniejszą rzeczą w tym przypadku o obietnicach będących monadą jest to, że prawdziwe jest następujące prawo:

Promise.resolve(Promise.resolve(x)) === Promise.resolve(x).

i ważniejsze od powyższego, to również ma dla dowolnej wartości x:

Promise.resolve(Promise.reject(x)) === Promise.reject(Promise.resolve(x)) === Promise.reject(x).

ta powyższa magiczna zasada jest tym, co uratowało mi moc myślenia na koniec dnia. Oznaczało to, że mogłem leczyć te błędy, gdy tylko się wydarzyły, wewnątrz ich własnych funkcji, trzymając się z dala od tego długiego łańcucha szaleństwa. Odpowiedź zawsze się na mnie gapiła, po prostu jej nie widziałam. Teraz widzę, i to jest piękne.

teraz to jest dobra, prawdziwa obietnica

oznaczało to, że mogłem po prostu mieć taką funkcję zapisu, na przykład:

function saveApplication() {
return makeApiCall().catch((err) => Promise.reject('basic'));
}

.blok catch oznacza, że obsługujemy błąd w podstawowym kroku formularza, ponieważ wywołanie saveApplication jest związane z krokiem formularza o nazwie basic. To doprowadziło nas do pięknego fragmentu kodu poniżej:

saveApplication()
.then(uploadImages)
.then(saveService)
.then(savePricingInfo)
.then(savePaymentInfo)
.then(gotoMainPage)
.catch((step) => {
setErrorState();
multiStepManager.go(step);
});

musieliśmy zmienić tylko jedną linię łańcucha obietnic, teraz wszystkie funkcje wewnątrz .następnie blokuje zwraca obietnicę, która już odrzuca do odpowiedniego kroku.

ale co jeśli zdarzały się inne rodzaje błędów, które nie były obsługiwane przez wewnętrzne zaczepy?

Cóż, można to łatwo rozwiązać, wdrażając niestandardowe typy błędów i oddzielając ocenę różnych typów błędów w naszym głównym .catch block. W ten sposób:

function saveApplication() {
return makeApiCall().catch((err) => Promise.reject(new StepError('basic')));
}//
saveApplication()
.then(uploadImages)
.then(saveService)
.then(savePricingInfo)
.then(savePaymentInfo)
.then(gotoMainPage)
.catch((step) => {
if(err instanceof StepError) {
setErrorState();
multiStepManager.go(step);
}
else {
// handle other types of errors
}
});

w tym przypadku głównym .blok catch obsługuje tylko błędy typu StepError. Inne rodzaje błędów są po prostu wyrzucane, a nie odrzucane, dzięki czemu mogą być odpowiednio obsługiwane przez aplikację lub przeglądarkę.

ta sama zasada może i powinna być rozszerzona o obsługę określonych typów błędów, takich jak różne statusy HTTP.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.