Это анти-паттерн (но вы не на сегодняшний день первый человек, который это сделает!):
.catch(error=>{
throw error;
})
Что говорит «Создайте новое обещание» «(потому что catch
создает обещание)» и если первоначальное обещание отклоняется, отклоните его с точно такой же причиной отказа (error
). » Так что это в основном неоперация, она ничего не делает. Это эквивалент обещания:
try {
// something
} catch (error) {
throw error;
}
Поскольку он ничего не делает, подумайте, как выглядит код без него - код нарушает одно из фундаментальных правил обещаний, а именно «обрабатывать отклонения или передать цепь чему-то еще, что будет ". : -)
Если вы хотите справиться с отклонением, не throw
из catch
:
Mysql.query("SELECT `password` \
FROM `m_users` \
WHERE `email` = ?",
['user@domain.tld'])
.then(ret=>{
if(ret.email) {
return res.send({
params: req.body,
message: 'Email address has already been taken.',
});
}
})
.catch(error=>{
// Use `error` here without `throw`ing -- report it, put it in a log, etc.
});
В обновлении вопроса вы показываете, что у вас есть все Ваш код, использующий обещания в try
/ catch
:
try {
Mysql.query(/*...*/)
.then(/*...*/)
.catch(error=>{
throw error;
});
}
catch( e )
{
console.log(e); // is never reached
}
В функции, отличной от async
, try
/ catch
не может отловить отклонения обещания, поскольку Когда обещание отклонено, исполнение уже покинуло блок try
. При непосредственном использовании обещаний вы используете метод catch
. Или вы используете функции async
(подробнее ниже).
Примечание: Node.js уже некоторое время поддерживает async
функции, которые, как правило, проще писать. В функции async
ваш код может быть:
// Within an `async` function
try {
const ret = await Mysql.query("SELECT `password` \
FROM `m_users` \
WHERE `email` = ?",
['user@domain.tld']);
if(ret.email) {
return res.send({
params: req.body,
message: 'Email address has already been taken.',
});
}
} catch (error) {
// Use `error` here without `throw`ing -- report it, put it in a log, etc.
}
Использование async
на верхнем уровне модуля также скоро появится ...
В комментарии вы спросили:
Я создаю MVC API и запускаю больше процедур на основе обещаний в том же методе контроллера. Я хотел бы вернуть сообщение, как только возникнет исключение, и прекратить продолжать выполнение следующих других обещанных процедур. Я обязан использовать метод async / await или есть другой способ?
Вам не нужно использовать async
/ await
, если вы не хотите, нет; они просто делают вещи проще (на мой взгляд).
Если вы не хотите использовать async
/ await
, в обратном вызове выполнения вы передаете then
, return обещание от следующей операции. Это заставляет обещание then
исполнять или отклонять в зависимости от того, что обещание выполняет следующая операция - в жаргоне обещания разрешает обещание от then
до , полученное от следующая операция.
Код стоит 1024 слова, поэтому:
doSomethingAsync()
.then(value => {
// ...use `value`, then
return doSomethingElseAsync();
})
.then(() => {
// ...
return doYetAnotherAsyncThing();
})
.catch(error => {
// Handle/report error here
});
Если любое из обещаний отклонено, любые последующие обработчики выполнения пропускаются, а обработчик отклонения в конце (добавляется через catch
) срабатывает.
Это примерно обещанная версия этого синхронного кода:
try {
const value = doSomethingSync();
// ...use `value`, then
doSomethingElseSync();
// ...
doYetAnotherSyncThing();
} catch (error) {
// Handle/report error here
}