2

我有一个用户控制器,它有一个创建方法,可以在创建用户之前检查数据库的电子邮件和用户名唯一性(这是为了解决 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()。

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

4

1 回答 1

2

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

至于将请求标记为坏后完成请求,我没有使用sails,但我过去可以通过使用res.send(). 编辑:查看文档后,似乎这是由 为您完成的.badRequest(),因此请忽略该部分。

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

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

  1. 使用Promise(注意:这是 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块中。例如;

    User.findOne({ email: req.body.email }, function(err, user) {
        if (user) { // or perhaps you want if (!err)
            User.create(...);
        } else {
            // handle error
        }
    });
    

就个人而言,我建议您使用 Promise(尤其是稍后,当您有长长的请求链一个接一个发生时),但请自行选择。

于 2014-10-01T19:47:01.767 回答