Я сталкивался с несколькими приложениями, где использование catch является более предпочтительным, чем rejectHandler. Например: предпочтение
new Promise.then(resolveHandler).catch()
вместо
new Promise().then(resolveHandler, rejectHandler).catch()
Есть ли конкретная причина для этого?
я нахожу
new Promise().then(resolveHandler, rejectHandler).catch()
быть более полезным, потому что
Кто-то знает какую-то конкретную причину, почему rejectHandler не используется много?
PS Я знаю о новых альтернативах в ES6, но мне просто интересно знать это.
Обновление: Я ЗНАЮ, КАК rejectHandler и лови работает. Вопрос в том, почему я вижу, что все больше людей используют только catch поверх rejectHandler и catch? Это лучшая практика или есть какое-то преимущество?
Обновление (добавив ответ сюда): Нашел ответ, который искал из первых рук. Причина не только в том, что ошибка в reject обрабатывается catch, это в основном из-за цепочки. Когда мы объединяем в цепочку prom.then.then.then.then, шаблон отклонения оказывается немного сложным, поскольку вы не захотите реализовать обработчик отклонений, просто чтобы переслать rejectData вверх по цепочке. Использование только обещания/затем/вылова вместе с разрешением/возвратом/броском оказывается очень полезным для создания цепочки из N чисел объектов. @Боб-Фангер (принятый ответ) тоже решил эту часть. Например:
getData(id) {
return service.getData().then(dataList => {
const data = dataList.find(data => {
return data.id === id;
});
if (!data) {
// If I use Promise.reject here and use a reject handler in the parent then the parent might just be using the handler to route the error upwards in the chain
//If I use Promise.reject here and parent doesn't use reject handler then it goes to catch which can be just achieved using throw.
throw {
code: 404,
message: 'Data not present for this ID'
};
}
return configuration;
});
}
//somewhere up the chain
....getConfiguration()
.then(() => {
//successful promise execution
})
.catch(err => {
if (err.code) {
// checked exception
send(err);
} else {
//unchecked exception
send({
code: 500,
message: 'Internal Server error: ${err}'
});
}
});
Использование только этого Все, что мне нужно беспокоиться, это обещание/затем/ловить вместе с разрешением/возвратом/выбросом в любом месте цепочки.
Разница в том, что если ошибка возникает в разрешенииHandler, она не будет обрабатываться откатомHandler, который обрабатывает только отклонения в первоначальном обещании.
Отрицательный Хэндлер не используется в сочетании с уловкой, потому что большую часть времени мы заботимся только о том, что что-то пошло не так.
Создание только одного обработчика ошибок делает код более понятным.
Если конкретное обещание в цепочке должно обрабатываться по-разному, что может быть причиной использования rejectHandler, но я, вероятно, напишу catch().then().catch()
Then catch().then().catch()
в этом случае.
Ни один из них более полезен, чем другой. Как отклоненный обработчик, так и обратный вызов catch вызывается при ошибке или обещание отклоняется.
Нет никакой "лучшей практики" для использования друг над другом. Вы можете видеть, что код использует тот или иной, но он будет основан на том, чего должен достичь код. Программист может захотеть поймать ошибку в разное время в цепочке и обработать ошибки, возникающие в разное время по-разному.
Надеюсь, следующее поможет объяснить, что я имею в виду:
somePromise
.then(
function() { /* code when somePromise has resolved */ },
function() { /* code when somePromise has thrown or has been rejected. An error thrown in the resolvedHandler will NOT be handled by this callback */ }
);
somePromise
.then(
function() { /* code when somePromise has resolved */ }
)
.catch(
function() { /* code when somePromise has thrown or has been rejected OR when whatever has occurred in the .then chained to somePromise has thrown or the promise returned from it has been rejected */ }
);
Обратите внимание, что в первом фрагменте, если обработчик разрешен, тогда нет обработанного обработчика (или catch
callback), который может уловить ошибку. Ошибка, вызванная разрешенным обратным вызовом, не будет улавливаться отвергнутымHandler, который указан как второй аргумент для. .then
Как указано в сообщении, предоставление разрешения и отклонения обработчика в том же призыве к. .then
позволяет отказаться от предыдущего обещания отдельно от ошибок, брошенных внутри, или возврата отклоненного обещания от обработчика успеха.
Поскольку обработчик отклонения, возвращающийся без ошибки, возобновляет фуфилированный канал цепочки обещаний, последний обработчик улова не будет вызываться, если предыдущий обработчик отклонения возвращается нормально.
Затем этот вопрос переходит к вариантам использования, стоимости разработки и уровня знаний.
В теории форма два параметра then
вызова может быть использована, чтобы повторить операцию. Но поскольку жестко закодированные цепочки обещаний настроены статически, повторная операция не является простой. Более простой способ повторить попытку может заключаться в использовании функции async
с утверждениями try-catch, await
обещания, которые могут потребоваться повторить, как в этом коде концепции:
async function() {
let retries = 3;
let failureErr = null;
while( retries--) {
try {
var result = await retryableOperationPromise()
return result;
}
catch( err) {
failureErr = err;
}
}
throw failureErr // no more retries
}
Другие варианты использования могут не распространяться.
Если говорить о том, что пользователь повторит попытку позже, он может быть дешевле, чем что-либо делать с конкретными причинами отказа от обещаний. Например, если я попытаюсь заказать рейс за полночь, когда авиакомпании повысят цены, мне обычно говорят "произошла ошибка, повторите попытку позже", потому что цена, которую я дал в начале бронирования, не будет соблюдена.
Я подозреваю, что использование обещаний часто может основываться на примере, а не на глубоком знании предмета. Также возможно, что руководители программ хотят, чтобы база кода была максимально простой для менее опытных разработчиков (вероятно, проблема с затратами).
"Лучшая практика" может действительно не применяться для принятия решений о том, как использовать обещания, если использование действительно. Некоторые разработчики и менеджеры будут избегать некоторых форм использования в принципе, но не всегда, исходя из технических достоинств.