lupausten Tao
Jos meillä olisi hieman enemmän kokemusta ja ymmärrystä lupauksista ja niiden käyttöä säätelevistä monadisista laeista, emme olisi käyttäneet niin paljon aikaa tämän koodinpätkän refaktorin työstämiseen.
Javascriptissä asynkronista koodia voidaan käsitellä lupauksilla, jotka ovat JavaScriptin Jatkumomonadeja. Tärkeintä tässä tapauksessa siitä, että lupaukset ovat monad, on, että seuraava laki on tosi:
Promise.resolve(Promise.resolve(x)) === Promise.resolve(x).
ja tärkeämpi kuin edellä mainittu, tämä pätee myös mille tahansa arvolle x:
Promise.resolve(Promise.reject(x)) === Promise.reject(Promise.resolve(x)) === Promise.reject(x).
Tämä yllä oleva taikasääntö pelasti minut lopulta ajatusvoimalta. Tämä tarkoitti sitä, että pystyin hoitamaan ne virheet heti, kun ne tapahtuivat, omien toimintojensa sisällä, pysyen poissa siitä pitkästä ketjuhulluudesta. Vastaus oli aina siellä tuijottamassa minua, en vain nähnyt sitä. Nyt näen, ja se on kaunis.
tämä tarkoitti sitä, että minulla voisi olla yksinkertaisesti tällainen saveapplication-funktio, esimerkiksi:
function saveApplication() {
return makeApiCall().catch((err) => Promise.reject('basic'));
}
the .catch block tarkoittaa, että käsittelemme virhettä lomakkeen perusaskeleella, koska saveApplication-kutsu liittyy basic-nimisen lomakkeen vaiheeseen. Tämä johti meidät kauniin koodin luo:
saveApplication()
.then(uploadImages)
.then(saveService)
.then(savePricingInfo)
.then(savePaymentInfo)
.then(gotoMainPage)
.catch((step) => {
setErrorState();
multiStepManager.go(step);
});
jouduimme vain vaihtamaan yhden lupausketjun rivin, nyt kun kaikki funktiot sisällä .sitten blocks palauttaa lupauksen, joka jo hylkää vastaavaan vaiheeseen.
mutta mitä jos tapahtuisi muunlaisia virheitä, joita sisäsaaliit eivät hoitaisi?
hyvin, että voitaisiin helposti ratkaista ottamalla käyttöön mukautettuja virhetyyppejä, ja erottamalla eri virhetyyppien arviointi pääosan sisällä .catch block. Näin:
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
}
});
tässä tapauksessa tärkein .catch block käsittelee vain steperror-tyypin virheitä. Muunlaisia virheitä vain heitetään, ei hylätä, jotta sovellus tai selain voivat käsitellä niitä vastaavasti.
samaa periaatetta voidaan ja tulee laajentaa käsittelemään tiettyjä virhetyyppejä, kuten erilaisia HTTP-tiloja.