Поскольку .findOne
уже возвращает Promise
, нет необходимости создавать новый с new Promise
- вместо этого, просто цепь на существующую Promise
цепь с .then
и .catch
по мере необходимости.Такие Promise
цепочки могут иметь любое число из .then
с и .catch
с - только то, что вы потребляете Promise
с одним .then
, не мешает вам использовать одно и то же значение разрешенияв другом месте.Для иллюстрации:
makePromise()
.then((result) => {
console.log(result);
// Returning inside a `.then` will pass along the value to the next `.then`:
return result;
})
.then((result) => {
// this `result` will be the same as the one above
});
Другими словами - нет необходимости создавать new Promise
каждый раз, когда вы захотите использовать еще один .then
.Итак:
Тогда я, вероятно, не смогу .then и .catch в findUserByEmail ("test@example.com")
не правильно -вы действительно можете приковать к концу существующего Promise с таким количеством .then
s и .catch
es, сколько захотите.
Обратите внимание, что .then
, который только возвращает свой параметр и больше ничего не делает (например,поскольку .then(currentUser => currentUser)
) излишне - оно вообще ничего не сделает.Также обратите внимание, что .catch
поймает Отклонения обещания и преобразуется в решено Promise
.Так что если вы сделаете
function findUserByEmail(email) {
return User.findOne({email: email})
.then(currentUser => currentUser)
.catch(error => error)
}
, то catch
означает, что абоненты findUserByEmail
будут не смогут catch
ошибки, потому что любые возможные ошибки были обнаружены в findUserByEmail
х catch
Обычно рекомендуется разрешить ошибкам просачиваться до вызывающей стороны функции, например, так:
someFunctionThatReturnsPromise('foobar')
.then((result) => {
// everything is normal, send the result
res.send(result);
})
.catch((err) => {
// there was an error, set response status code to 500:
res.status(500).send('there was an error');
})
Так, если только ваша findUserByEmail
илиcreateNewUser
вспомогательные функции необходимо сделать что-то конкретное при возникновении ошибки, вероятно, было бы лучше просто вернуть только Promise
:
const findUserByEmail = email => User.findOne(email);
const createNewUser = newUserDetails => new User(newUserDetails).save();
Если ваши вспомогательные функции do нужно что-то делать при возникновении ошибки, а затем, чтобы убедиться, что ошибка передается должным образом вызывающей функции, я бы рекомендовал либо выбросить ошибку внутри catch
:
const findUserByEmail = email => User.findOne(email)
.catch((err) => {
// error handling - save error text somewhere, do a console.log, etc
throw err;
});
, чтобы вы могли catch
, когда что-то еще вызывает findUserByEmail
.В противном случае, если вы сделаете что-то вроде
const findUserByEmail = email => User.findOne(email)
.catch((err) => {
// do something with err
return err;
});
, то вызывающий findUserByEmail
должен будет проверить внутри .then
, если результат действительно является ошибкой, что странно:
findUserByEmail('foo@bar.com')
.then((result) => {
if (result instanceof Error) {
// do something
} else {
// No errors
}
});
Лучше выдать ошибку в findUserByEmail
catch
, так что потребитель findUserByEmail
может также .catch
.