猫鼬 - 一次多次使用findOne

时间:2016-04-08 10:19:01

标签: node.js mongoose

免责声明:我是一名新手网络开发者。

我正在创建一个注册页面。有5个输入字段,其中3个(用户名,密码和电子邮件)要求它们通过各种形式的验证。这是代码:

router.post('/register', function (req, res, next) {
user.username = req.body.username;
user.profile.firstName = req.body.firstName;
user.profile.lastName = req.body.lastName;
user.password = req.body.password;
user.email = req.body.email;

User.findOne({email: req.body.email}, function(err, existingEmail) {

    if(existingEmail) {
        console.log(req.body.email + " is already in use")
    } else {
        User.findOne({username: req.body.username}, function(err, existingUsername) {
            if(existingUsername) {
                console.log(req.body.username + " is already in use");
            } else {
                user.validate({password: req.body.password}, function(err) {
                    if (err) {
                        console.log(String(err));
                    } else {
                        user.save(function(err, user) {
                            if (err) {
                                return next(err);
                            } else {
                                return res.redirect('/')
                            }
                        })
                    }
                });
            }
        });
    }
});
});

基本上它首先检查它是否是重复的电子邮件;如果是重复的电子邮件,它会在console.log中说明。如果它不是重复的电子邮件,则它会检查用户名....然后输入密码。

问题在于它一次完成所有这一切;如果用户输入了错误的电子邮件和用户名,则只会说电子邮件不正确(不会说电子邮件和用户名都不正确)。

如何让它同时验证所有3个表格?

2 个答案:

答案 0 :(得分:1)

您可以使用async并行运行它们,它还可以使您的代码更清晰,并处理该回调地狱:

var async = require('async');

async.parallel([
  function validateEmail(callback) {
    User.findOne({email: req.body.email}, function(err, existingEmail) {
      if(existingEmail) {
        callback('Email already exists');
      } else {
        callback();
      }
    }
  },
  function validateUsername(callback) {
    User.findOne({username: req.body.username}, function(err, existingUsername) {
      if(existingUsername) {
        callback('Username already exists');
      } else {
        callback();
      }
    }
  },
  function validatePassword() {
    user.validate({password: req.body.password}, function(err) {
      if(err) {
        callback(err);
      } else {
        callback();
      }
    }
  }
], function(err) {
    if(err) {
      console.error(err);
      return next(err);
    } else {
      user.save(function(err, user) {
        if (err) {
          return next(err);
        } else {
          return res.redirect('/');
        }
      });
    }
  }
);

这样,数组中的所有验证方法都将并行运行,当所有验证方法都完成后,将保存用户。

答案 1 :(得分:0)

如果您使用else语句,则选择按设计单独进行检查(一次一个)。

为了实现'一次性'行为,我不会使用else语句(如果可能,即错误对于下次检查不会致命),但是会在同一个块中进行所有测试,并且会填充像这样的对象:

errors: {
  existingEmail: false,
  existingUserName: false,
  invalidUserName: false,
  wrongPassword: false,
  ...
};

然后我会在表单中使用它来向用户显示所有错误......

这样的事情:

var errors = {};
if (existingEmail) {
    console.log(req.body.email + " is already in use");
    errors.existingEmail: true;
}
User.findOne({username: req.body.username}, function(err, existingUsername) {
    if (existingUsername) {
        console.log(req.body.username + " is already in use");
        errors.existingUsername: true;
    } else {
        user.validate({password: req.body.password}, function(err) {
            if (err) {
                console.log(String(err));
                errors.invalidUsername = true;
            } else {
                user.save(function(err, user) {
                    if (err) {
                        return next(err);
                    } else {
                        return res.redirect('/')
                    }
                })
            }
        });
    }
});