Išimtys JavaScript pažadų grandinėse
Tarkime, dėl kokių nors priežasčių mūsų pažadas baigsis klaida:
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('error');
}, 3000);
});
Tokiu atveju kodo vykdymas iš karto pereis
prie to then, kuriame yra klaidos apdorojimo funkcija,
arba prie pirmo catch, priklausomai nuo to,
kas pasitaikys anksčiau.
Štai pirmos situacijos pavyzdys:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
},
function(error) {
// vykdymas iš karto pereis čia
}
).then(
function(result) {
console.log(result);
}
);
Štai antros situacijos pavyzdys:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// vykdymas iš karto pereis čia
}
).then(
function(result) {
console.log(result);
}
);
Apdorojimo funkcija turi du veiksmų variantus:
jei ji susidorajo su išimtine situacija,
tai gali grąžinti rezultatą per return
ir vykdymas tęsis toliau grandine.
Jei ji nesusidorajo su klaida, tai gali
arba nieko negrąžinti, arba išmesti išimtį
per throw. Tokiu atveju vykdymas
pereis prie kito klaidų gaudytojo
(į then arba catch – kas pasitaikys
anksčiau).
Paprastai visos grandinės klaidos sulaikomos
vienoje vietoje: grandinės pabaigoje dedamas
catch:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// pateksime čia klaidos atveju
}
);
Be to, išimtis gali atsirasti pačiame
pažade arba būti išmesta per throw
bet kuriame grandinės grandyje:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
if (viskasGerai) {
return result + '2';
} else {
throw new Error('klaida'); // pereiname prie artimiausio gaudytojo
}
}
)
.then(
function(result) {
return result + '3';
}
).catch(
function(error) {
// artimiausias gaudytojas
}
);
Turėkite omenyje, kad catch reikalingas būtent
klaidai diagnozuoti: ar ji išsprendžiama, ar ne.
Jei klaida išsprendžiama, tai catch turėtų
perduoti jos sprendimą sekančiam po savės then.
O jei neišsprendžiama (ar šis catch
tiesiog nežino, kaip ją išspręsti), tai mes turime
arba nieko negrąžinti, arba mesti išimtį:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
if (klaidaIšsprendžiama) {
return 'duomenys'; // siunčiame į sekantį then
} else {
// nieko negrąžiname arba metame išimtį
}
}
).then(
function(result) {
// čia sprendžiame klaidą
}
);