Выключэнні ў ланцужках промісаў у 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) {
// тут вырашаем памылку
}
);