我有一个用户 Controller ,它有一个创建方法,可以在创建用户之前检查数据库的电子邮件和用户名唯一性(这是为了解决 SailsJS 的 mongodb adpater 中不支持唯一属性标志的错误) - 版本 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() - 执行并未结束。我怀疑 return res.badRequest 将控制权返回给调用函数 (User.findOne),并从那里继续执行。
我尝试使用 res.badRequest().end() 但这会使客户端挂起(没有响应),并在返回 res.badRequest() 后使用 res.end() 生成“ header 发送”错误。
如果发现现有电子邮件,我如何结束此请求的执行?
最佳答案
首先,您的 findOne
在这里是一个 find
。这与您的问题无关,但有点令人困惑,您应该确保以您期望的格式获取数据。
至于将请求标记为错误后完成请求,我没有使用过 sails,但我过去可以通过使用 res.send()
来结束执行。编辑:查看文档后,这似乎是由 .badRequest()
为您完成的,因此请忽略该部分。
也就是说,即使那实际上也不是你的问题。您的问题是您启动了一个异步 User.find()
,然后您立即开始运行 User.create()
(也是异步的) ,因此您的请求不会被标记为错误,直到您尝试创建新用户之后。
您需要做的是以下两件事之一:
使用promises (注意:这就是 Mongoose 的工作方式;Sails 可能有所不同)仅在
User.find()
完成后运行User.create()
。例如;var userQuery = User.findOne({ email: req.body.email }).exec(); userQuery.addBack(function(err, user) { if(!!user) res.badRequest('...'); else create_user(); });
将用户创建逻辑放入
findOne
block 内部。例如;User.findOne({ email: req.body.email }, function(err, user) { if (user) { // or perhaps you want if (!err) User.create(...); } else { // handle error } });
就我个人而言,我建议您使用 Promise(尤其是在以后,当您有一长串请求一个接一个地发生时),但请您选择。
关于sails.js - 如何从 findOne() 回调发送最终响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149046/