在后端API我有应执行以下动作序列的登录路由:Express.js和蓝鸟 - 处理的承诺链
给定一个用户名和密码,尝试对用户进行身份验证一个Active Directory。如果身份验证失败,则回复状态401.如果成功,请继续。
在数据库中查找具有给定用户名的用户。如果没有找到答复状态403,则继续。
查找用户文档是否包含电子邮件,显示名称等详细信息(如果这不是第一次登录)。如果是回复用户对象,否则继续。
从Active Directory获取用户详细信息并更新数据库中的用户对象。用更新的对象回复。
代码:
router.post('/login', (req, res, next) => {
// capture credentials
const username = req.body.username;
const password = req.body.password;
let user = null;
// authenticate
ad.authenticate(username, password)
.then((success) => {
if (!success) {
res.status(401).send(); // authentication failed
next();
}
return User.findOne({ username }).exec();
})
.then((found) => {
if (!found) {
res.status(403).send(); // unauthorized, no account in DB
next();
}
user = found;
if (user.displayName) {
res.status(201).json(user); // all good, return user details
next();
}
// fetch user details from the AD
return ad.getUserDetails(username, password);
})
.then((details) => {
// update user object with the response details and save
// ...
return user.save();
})
.then((update) => {
res.status(201).json(update); // all good, return user object
next();
})
.catch(err => next(err));
});
现在我有这个与回调运行,但它真的嵌套。所以,我想给蓝鸟承诺一试,但我有两个问题:
看起来杂乱无章,没有更好的办法来链调用和处理响应?
无论何时我在回复后致电
next()
停止请求,执行继续到其他.then()
。虽然客户端收到正确的响应,但在服务器日志中,我发现执行仍在继续。例如,如果给定用户的数据库中没有帐户,则客户端收到403
响应,但在服务器日志中,我看到一个例外failed to read property displayName of null
,因为没有用户,它应该在res.status(403).send();
之后的next()
处停止。
我目前使用的是最新的节点版本7,并启用了'--harmony-async-await',然后可以使用async/await模式,真的可以清理代码。 – Keith
你必须'return next()' – ThomasThiebaud