我有一个用户控制器,它有一个create方法,可以在创建用户之前检查数据库的电子邮件和用户名唯一性(这是为了解决mailsodb adpater中不支持唯一属性标志的SailsJS中的错误 - 版本0.10.5)。
代码如下所示:
User.find({ email: req.body.email }, function (err, user) {
if(user) {
return res.badRequest('Unique email constraint. Email is already used.');
}
});
User.create(req.body).exec(function (err, user) {
// Code to catch and manage err or new user
}
我的期望是,如果电子邮件已存在于数据库(mongodb)中,使用res.badRequest()发送400,则执行结束。
发生的是响应被发送,但随后控制移动到User.create() - 执行没有结束。我怀疑返回res.badRequest正在将控制权返回给调用函数(User.findOne),并从那里继续执行。
我尝试使用res.badRequest()。end()但是让客户端挂起(没有响应),并在返回res.badRequest()之后使用res.end()生成'header send'错误。
如果找到现有电子邮件,如何执行此请求?
答案 0 :(得分:2)
首先,您的findOne
在这里find
。这与您的问题无关,但有点令人困惑,您应该确保以您期望的格式获取数据。
至于在标记为坏之后完成请求,我没有使用风帆,但我能够使用res.send()
结束执行。编辑:在查看文档之后,.badRequest()
似乎已经为您完成了,所以请忽略该部分。
那就是说,即使这不是你的问题。您的问题是您启动异步User.find()
,然后您立即开始运行User.create()
(也是异步),因此您的请求不会被标记为坏在之后,您已尝试创建新用户。
您需要做的是以下两件事之一:
使用promises(注意:这是它对Mongoose的作用方式; Sails可能有所不同)仅在User.create()
完成后运行User.find()
。例如;
var userQuery = User.findOne({ email: req.body.email }).exec();
userQuery.addBack(function(err, user) {
if(!!user) res.badRequest('...');
else create_user();
});
将您的用户创建逻辑放在 findOne
块中。 e.g;
User.findOne({ email: req.body.email }, function(err, user) {
if (user) { // or perhaps you want if (!err)
User.create(...);
} else {
// handle error
}
});
就我个人而言,我建议您使用承诺(特别是稍后,当您有一长串请求发生在另一个之上时),但请选择。