【问题标题】:How to run multiple queries, express/mongoose validation如何运行多个查询,表达/猫鼬验证
【发布时间】:2017-06-08 22:08:13
【问题描述】:

我正在尝试验证登录表单。现在我正在努力让用户名和电子邮件验证部分正常工作。

这两个字段都应该是唯一的,正如我的架构中指定的那样。

var userSchema = new mongoose.Schema({
  username: {type:String,required:true,trim:true,unique:true},
  password:{type:String,required:true},
  email:{type:String,required:true,unique:true},
  verified:{type:Boolean,required:true},
  dateCreated:{type:Date,default:Date.now}
});

我还在架构上定义了一个静态方法。

userSchema.statics.validateSignUp = function(username,useremail,password,passwordConfirmation,callback,next){
  var isValid = true;
  var User = this;
  var errorObject = {};
  if(username.trim().length >= 5){
    //check to see if username already exists
    User.findOne({'username': username}).exec(function(err,user){
        if(err){
          return next(err);
        }
        if(user){
          isValid = false;
          errorObject.username = 'Username is already taken.';
        }
      });
  }else{
    isValid = false;
    errorObject.username = 'Username must be at least 5 chars long.';
  }

  //check to see if password is greater than 5 characters
  //if not add to responseJson errors
  if(password.length < 5){
    isValid = false;
    errorObject.password = 'Password must be at least 5 chars long.';
  }

  //check password confirmation
  if(password !== passwordConfirmation){
    isValid = false;
    errorObject.passwordConfirm = 'Passwords do not match.';
  }

  //check email against regex
  var emailRe = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  if(emailRe.test(useremail)){
    User.findOne({'email':useremail}).exec(function(err,user){
        if(err){
          return next(err);
        }
        if(user){
          isValid = false;
          errorObject.email = 'User with this email already exists.';
        }
      });
  }else{
    isValid = false;
    errorObject.email = 'Email is not valid.';
  }
  if(!isValid){
    console.log('not valid')
    return errorObject;
  }else{
    console.log('valid')
    callback()
  }
}

代码应该在尝试通过回调函数保存之前查看数据库中是否已经存在用户名和电子邮件。但是,当我测试它时,该方法会不断返回 isValid = true。我认为这是由于 Node 的异步特性。如果是这样,处理这类事情的好方法是什么?

【问题讨论】:

    标签: node.js forms mongodb express mongoose


    【解决方案1】:

    使用Promiseasync

    这是使用Promise 的示例代码。我将验证分解为更小的函数(每个函数返回一个promise),然后将这些承诺链接起来。

    理想情况下,从主函数返回一个承诺会更简单,但请记住,您的剩余代码已经使用callbacknext 等设置,我保留了回调方式。用法示例在代码末尾。

    另外,你真的需要下一个吗?你有回电!

    见代码末尾的用法示例。

    userSchema.statics.validateSignUp = function (username, useremail, password, passwordConfirmation, callback, next) {
    
        var isValid = false;
        var User = this;
        var errorObject;
    
        const checkUsername = function () {
            return new Promise(function (resolve, reject) {
                errorObject.username = 'Username must be at least 5 chars long.';
                if (username.length < 5) return resolve(errorObject);
    
                User.findOne({ username: username }).exec(function (err, user) {
                    if (err) return reject(err);
                    if (user) errorObject.username = 'Username is already taken.';
                    return resolve();
                });
            });
        };
    
        const checkPassword = function () {
            return new Promise(function (resolve, reject) {
    
                if (password.length < 5) {
                    errorObject.password = 'Password must be at least 5 chars long.';
                    return resolve();
                }
    
                if (password === passwordConfirmation) return resolve();
    
                errorObject.password = 'Passwords do not match.';
                resolve();
            });
        };
    
        const checkEmail = function () {
            return new Promise(function (resolve, reject) {
    
                var emailRe = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    
                if (!emailRe.test(useremail)) {
                    errorObject.email = 'Email is not valid.';
                    resolve();
                }
    
                User.findOne({ 'email': useremail }).exec(function (err, user) {
    
                    if (err) return reject(err);
    
                    if (user) {
                        errorObject.email = 'User with this email already exists.';
                        resolve();
                    }
    
                    isValid = true;
                    resolve();
                });
    
            });
        };
    
        checkUsername()
            .then(checkPassword)
            .then(checkEmail)
            .then(function () {
    
                // if (isValid) console.log('valid');
                // else console.log('not valid');
    
                callback(errorObject, isValid);
    
            })
            .catch(function (err) {
                next(err);
            });
    };
    
    
    //USAGE EXAMPLE:
    
    // userModel.validateSignUp('foo', 'foo@bar.com', 'bar', 'bar', function (err, valid) {
    
    //     if (err) return console.log(err);
    
    //     if (valid) console.log('valid');
    //     else console.log('not valid');
    
    // }, next);
    

    希望对你有所帮助。

    【讨论】:

    • 非常感谢。我一直在花最后一小时查找 ES6 承诺。这正是我走上正轨所需要的。
    猜你喜欢
    • 2020-12-25
    • 2021-08-03
    • 2021-08-02
    • 2017-04-18
    • 2020-02-16
    • 2011-11-14
    • 2017-06-04
    • 2019-10-24
    • 2018-09-08
    相关资源
    最近更新 更多