С Javascript Promises, есть ли лучшие практики в отношении использования «ошибок» по сравнению с предложениями catch?
Не существует универсальной «лучшей практики» для этого вопроса, потому что это зависит от на каком конкретном c поведении вы хотите, чтобы ваш код имел. Как уже упоминали другие, вы получаете другое поведение несколькими способами.
Некоторые авторы, кажется, используют один подход, другие авторы используют другой, и мне не ясно, почему. Есть ли ситуации, в которых необходимо или желательно использовать одно или другое?
Да, есть ситуации, когда можно использовать одно или другое. Они обеспечивают потенциально разное поведение. Только если вы на 200% уверены, что ваш successHandler
in .then(successHandler)
никогда не сможет выбросить или вернуть отклоненное обещание, не будет значимой разницы.
Вкратце:
Когда при использовании p.then(successHandler).catch(errorHandler)
, errorHandler
будут получены ошибки, которые возникают либо из-за отклоненного p
, либо из-за ошибки или отклонения из successHandler
.
При использовании p.then(successHandler, errorHandler)
будет вызываться errorHandler
из-за отклонения p
и НЕ будет вызван из-за ошибки или отклонения из successHandler
.
Различное поведение, которое полезно для разных обстоятельств.
В этом .catch()
, приведенный ниже, .catch()
перехватит возникшую ошибку (случайно из-за ошибки кодирования, вызванного исключения или при возврате какого-либо другого обещания, которое отклоняет).
Promise.resolve("hello").then(greeting => {
console.log("throwing error");
throw new Error("My .then() handler had an error");
}).catch(err => {
// will get here
console.log("Caught error in .catch()\nError was: ", err.message);
});
Но при использовании второго аргумента для .then()
эта ошибка обработчика .then()
не будет обнаружена:
Promise.resolve("hello").then(greeting => {
console.log("throwing error");
throw new Error("My .then() handler had an error");
}, err => {
// won't get here
console.log("Caught error in .catch()\nError was: ", err.message);
});
Итак, иногда вы хотите, чтобы ошибка, которая может возникнуть в обработчике .then()
, поразила этот обработчик немедленной ошибки, а иногда вы не хотите, чтобы она ударила этот обработчик ошибок, потому что вы хотите, чтобы этот обработчик ошибок обрабатывал только ошибки из исходного обещания, и у вас есть другой обработчик catch позже в цепочке обещаний, который будет обрабатывать эту ошибку.
Рекомендация
В общем, я бы посоветовал вам начать с обработчика .catch()
, потому что он улавливает больше ошибок и не требует наличия другого .catch()
обработчика в другом месте цепочки обещаний, чтобы быть в безопасности. Затем вы переключаетесь на форму .then(successHandler, errorHandler)
, если вы явно не хотите, чтобы этот errorHandler
вызывался, если есть другая ошибка в successHandler
И у вас есть где-то еще в цепочке обещаний, где ошибка в successHandler
будут пойманы или схвачены.