Tao Of Promises
med litt mer erfaring og forståelse Av Løfter og monadiske lover som styrer bruken, ville vi ikke ha brukt så mye tid på å jobbe på refactor av dette stykke kode.
I JavaScript kan asynkron kode håndteres via Løfter, som Er Fortsettelsesmonadene Til JavaScript. Det viktigste i Dette tilfellet Om Løfter som en monad er at følgende lov er sant:
Promise.resolve(Promise.resolve(x)) === Promise.resolve(x).
og viktigere enn den ovenfor, denne har også for noen verdi x:
Promise.resolve(Promise.reject(x)) === Promise.reject(Promise.resolve(x)) === Promise.reject(x).
denne magiske regelen ovenfor er det som reddet meg litt tankekraft på slutten av dagen. Dette betydde at jeg kunne behandle disse feilene så snart de skjedde, i sine egne funksjoner, holde seg borte fra den lange kjeden galskap. Svaret var alltid der og stirret på meg, jeg kunne bare ikke se det. Nå ser jeg, og det er vakkert.
dette betydde at jeg bare kunne ha saveapplication-funksjonen som dette, for eksempel:
function saveApplication() {
return makeApiCall().catch((err) => Promise.reject('basic'));
}
den .catch block betyr at vi håndterer en feil på grunntrinnet i skjemaet, fordi saveApplication-anropet er relatert til trinnet i skjemaet som kalles basic. Dette førte oss til den vakre stykke kode ned nedenfor:
saveApplication()
.then(uploadImages)
.then(saveService)
.then(savePricingInfo)
.then(savePaymentInfo)
.then(gotoMainPage)
.catch((step) => {
setErrorState();
multiStepManager.go(step);
});
Vi måtte bare endre en enkelt linje Av Løftet kjeden, nå som alle funksjonene inne i .deretter returnerer blokker Et Lofte som allerede avviser til det tilsvarende trinnet.
men hva om andre typer feil skjedde, som ikke ble håndtert av de indre fangstene?
vel, det kan lett løses ved å implementere tilpassede feiltyper, og skille evalueringen av ulike feiltyper i vår hoved .fang blokk. Som dette:
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
}
});
i dette tilfellet er hoved .catch block håndterer bare feil av Typen Steeperror. Andre typer feil blir bare kastet, ikke avvist, slik at de kan håndteres tilsvarende av programmet eller nettleseren.
det samme prinsippet kan og bør utvides til å håndtere bestemte feiltyper, for eksempel FORSKJELLIGE HTTP-statuser.