Изключения в вериги от промени в JavaScript
Нека по някакви причини нашият промис завърши с грешка:
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('error');
}, 3000);
});
В този случай изпълнението на кода веднага ще премине
към оня then, в който има функция-обработчик
на грешката, либо към първия catch, гледайки
кое ще се срещне по-рано.
Ето пример за първата ситуация:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
},
function(error) {
// изпълнението веднага ще премине тук
}
).then(
function(result) {
console.log(result);
}
);
Ето пример за втората ситуация:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// изпълнението веднага ще премине тук
}
).then(
function(result) {
console.log(result);
}
);
Функцията-обработчик има два варианта на действие:
ако тя се е справила с изключителната ситуация,
то може да върне резултат чрез return
и изпълнението ще продължи по-нататък по веригата.
Ако пък не се е справила с грешката, то може
или да не върне нищо, или да хвърли изключение
чрез throw. В този случай изпълнението
ще премине към следващия прихващач на грешки
(в then или catch - което се срещне
по-рано).
По правило всички грешки във веригата се прихващат
на едно място: в края на веригата се поставя
catch:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// ще попаднем тук в случай на грешка
}
);
При това изключение може да възникне в самия
промис, или да бъде хвърлено чрез throw
във всяка връзка от веригата:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
if (всичкоДобре) {
return result + '2';
} else {
throw new Error('грешка'); // преминаваме към най-близкия прихващач
}
}
)
.then(
function(result) {
return result + '3';
}
).catch(
function(error) {
// най-близкият прихващач
}
);
Имайте предвид, че catch е необходим точно за
диагностика на грешката: решимима ли е или не.
Ако грешката е решимима, то catch трябва
да предаде нейното решение на следващия след себе си then.
А ако не е решимима (или този catch
просто не знае как да я реши), то трябва
или да не върнем нищо, или да хвърлим изключение:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
if (грешкатаЕРешимима) {
return 'данни'; // изпращаме на следващия then
} else {
// не връщаме нищо или хвърляме изключение
}
}
).then(
function(result) {
// тук решаваме грешката
}
);