Ваш обработчик then
в конце всегда запускается (хорошо, если обещания не отклоняются), потому что первое обещание разрешается с undefined
, если пользователь не существует, или с логическим значением, если пользователь делает есть.
Ваша вложенная версия была в порядке. Если вам нужно вернуть user
в успешном случае, возможно, это правильный путь.
Но если вам просто нужно вернуть 'ok'
, как в вашем втором примере кода в успешном случае, вы могли бы сгладить вещи, вам просто нужно обработать undefined
, который вы получите, если есть нет пользователя Мы также можем воспользоваться тем фактом, что вы знаете, что user
будет иметь значение undefined
, если пользователь не был найден:
return this.userRepository.findOne({ username: username, enable: true })
// The `then` below returns `undefined` if `user` is `undefined`, the promise from `compare` otherwise
.then((user: User | undefined) => user && bcrypt.compare(password, user.password))
.then(passwordMatch => {
if (passwordMatch === undefined) {
// No user
return undefined;
} else if (!passwordMatch) {
// Bad password
throw new ForbiddenError('Authentication failed.'); // 403
} else {
// All good
return 'ok';
}
});
Если вы хотите сгладить его и вернуть user
, то вам нужно передать user
следующему обработчику:
return this.userRepository.findOne({ username: username, enable: true })
.then((user: User | undefined) => {
return !user
? {user} // will be {undefined}
: bcrypt.compare(password, user.password)
.then(passwordMatch => ({user, passwordMatch})); // *** Note making an object
})
.then(({user, passwordMatch}) => { // *** Note destructuring
if (user === undefined) {
// No user
return undefined;
} else if (!passwordMatch) {
// Bad password
throw new ForbiddenError('Authentication failed.'); // 403
} else {
// All good
return user; // 200
}
});
(Этот первый обработчик then
мог быть сжатой стрелкой, как в первом блоке кода выше, но он стал уродливым.)