router.post('/login', (req, res) => {
let user;
User.findOne({
username: req.body.username
}).then(_user => {
if (!_user) {
return res.status(401).json({
message: 'Username or password is incorrect'
});
}
user = _user;
return bcrypt.compare(req.body.password, _user.passwordHash);
}).then(valid => {
if (!valid) {
return res.status(401).json({
message: 'Username or password is incorrect'
});
}
try {
const token = jwt.sign({ username: user.username, id: user._id },
"somesecret", { expiresIn: '1h' }
);
}
catch (err){
console.log(err);
}
return res.status(200).json({
token: token
});
}).catch(err => {
console.log(err);
return res.status(500).json({
message: 'Internal Server Error'
});
})
});
从第一个“ User.findOne”回调中,我想将响应发送回客户端并立即终止该函数,但是它只会从第一个匿名回调函数中返回,然后继续执行第二个匿名回调函数,以检查变量“有效”和意外情况会发生,例如第二次编写响应并导致更多错误。有没有更好的方法来实现所有这些?
假设您使用express js,则需要使用res / end来结束响应。之后返回。https://expressjs.com/en/api.html#res.end
在评论中与您交谈后,我仍然不明白为什么要链接诺言,但是如果您想按照自己的方式去做,那么跳过“然后”的一种方法就是抛出一个错误,这将带您进入“捕获”部分。试试这个,告诉我这是否是您想要的行为。
而不是:
return res.status(401).json({
message: 'Username or password is incorrect'
});
尝试:
res.status(401).json({
message: 'Username or password is incorrect'
});
res.end();
throw new Error("Username or password is incorrect")
这将跳到最后。
如果这不是您希望的方式,则需要解释-回报是什么?您想返回什么,何时返回?您的退货和明确的答复之间有区别吗?流程对我来说还不够清楚。
如果您仍要使用Promise时要使用更干净的代码,则可以使用async await。在这里阅读:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function