如何从findOne()回调发送最终响应?

时间:2014-10-01 19:27:19

标签: sails.js sails-mongo

我有一个用户控制器,它有一个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'错误。

如果找到现有电子邮件,如何执行此请求?

1 个答案:

答案 0 :(得分:2)

首先,您的findOne在这里find。这与您的问题无关,但有点令人困惑,您应该确保以您期望的格式获取数据。

至于在标记为坏之后完成请求,我没有使用风帆,但我能够使用res.send()结束执行。编辑:在查看文档之后,.badRequest()似乎已经为您完成了,所以请忽略该部分。

那就是说,即使这不是你的问题。您的问题是您启动异步User.find(),然后您立即开始运行User.create()(也是异步),因此您的请求不会被标记为坏之后,您已尝试创建新用户。

您需要做的是以下两件事之一:

  1. 使用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();
    });
    
  2. 将您的用户创建逻辑放在 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
        }
    });
    
  3. 就我个人而言,我建议您使用承诺(特别是稍后,当您有一长串请求发生在另一个之上时),但请选择。