Исключения в цепочках промисов в 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) {
// тут решаем ошибку
}
);