0

在注册时,我检查数据库以查看用户名和电子邮件是否存在,如果存在,它应该返回错误。所有用户名和电子邮件都应该是唯一的。看来我的问题是我只能得到一个错误。如果电子邮件已经存在,我会收到 Flash 消息,但如果用户名也存在,则不会说明用户名已经存在。我想显示这两个错误如果两个错误都已经存在于帖子中

我假设问题是返回done()电子邮件。因为我有 2 个查询它只查看第一个被击中的查询。我真的不知道。

我试图对此进行研究,我知道您可以为 req.flash 传入一个数组,但我只是可以让它工作,因为它返回了它看到的第一个我认为存在的数组。

我还读到 for 的第三个参数done是一个 info 对象,我认为它提供了有关用户的信息,我正在考虑在那里加载现有信息,但我无法将它们放在一起。我也尝试了其他东西。但是我只会向您展示与查询数据库有关的东西,因为我失败了

passport.use("local-signup", new LocalStrategy({
    usernameField : "email",
    passwordField : "password",
    passReqToCallback : true
},
    function(req, email, password, done){
        var arr = [];
        User.findOne({"email" : email}, function(err, user){
            if(err) return done(err);
            if(user){
                // arr.push("That email is already taken")
                return done(null, false, req.flash("signupMessage", "That username is taken"))
            }else{
                User.findOne({"username" : req.body.username}, function(err,user){
                    if(err) return done(err);
                    if(user){
                        // arr.push()
                        return done(null, false, req.flash("signupMessage", "That username is taken"))
                    }else{
                        var newUser = new User();
                        newUser.username = req.body.username;
                        newUser.password = password;
                        newUser.email = req.body.email;

                        newUser.save(function(err, doc){
                            if(err) throw err;
                            console.log("doc", " " , doc)
                            return done(null, newUser);
                        })                          
                    }
                })

            }
        })
    }
))

EJS

app.get("/signup", function(req, res){
    console.log(req.session)
    console.log(req.flash("signupMessage"))
    res.render("signup", {authed : authed, user : user, message: req.flash("signupMessage")})
})
app.post("/signup",passport.authenticate("local-signup", {
    successRedirect : "/",
    failureRedirect : "/signup",
    failureFlash : true
}))
4

3 回答 3

0

调整控制流是解决此问题的一种方法,但如果您正在寻找更优雅的解决方案,那么您可以尝试这种promise.all()方法。

它的promise.all()作用是它实际上一次触发所有异步调用并在何时返回;

  1. 所有异步调用都成功(解决)
  2. 任何 1 个异步调用都返回拒绝(失败)

显然,第 2 点不是您要寻找的东西,因为您想同时报告电子邮件和用户名以防它们不是唯一的情况。

要解决此问题,您必须仅在所有承诺都已回复(成功或失败)时才使用 return reflectpromise.all()

考虑下面的代码:

this.reflect = function reflect(promise){
  return promise.then(function(/*resolve return value=*/v){ return { v:v, status: "resolved" }},
      function(/*rejection error=*/e){ return { e:e, status: "rejected" }});
};

var promises = [
  new Promise(function(resolve, reject) {
    // User.findOne({"username" : req.body.username}, function(err,user){
    // if (err) { return reject("error!"); }...
    // resolve("Name is unique!!");
    // });
    resolve("name is unique");
  }),
  new Promise(function(resolve, reject) {
    reject("email is NOT unique");
  })
];

Promise.all(promises.map(this.reflect)).then(function(results) {
  if (results[0].status === "rejected") {
    console.log("Error reason: " + results[0].e);
  }
  else {
    console.log("Succeeds, reason: " + results[0].v);
  }
  if (results[1].status === "rejected") {
    console.log("Error reason: " + results[1].e);
  }
  else {
    console.log("Succeeds, reason: " + results[1].v);
  }

  // You can call whatever callback you want here.
  // e.g. return done(null, "Test");
});

输出:

成功,原因:名称是唯一的
错误原因:电子邮件不是唯一的

注意: 您应该能够对上面的代码进行一些更改以满足您的需要。如果您仍然遇到问题,请大声告诉我。

参考:
https ://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

于 2016-07-27T04:49:04.953 回答
0

这是一个基本的控制流问题。你的归来。不。将不得不重复一些代码作为它的额外功能,或者使用一个标志并在之前点击数据库。也不确定如何显示这两条消息,必须单独解决。将它们合并为一个(“用户名和电子邮件已注册。请输入不同的用户名和电子邮件ID。”)

User.findOne({"email" : email}, function(err, user){
        if(err) return done(err);
        if(user){
            // arr.push("That email is already taken")
        // do not know what all done does maybe a ligther versio that just sends the error
            done(null, false, req.flash("signupMessage", "That Email is taken"))

        User.findOne({"username" : req.body.username}, function(err,user){
                if(err) return done(err);
                if(user){
                    // arr.push()
                    return done(null, false, req.flash("signupMessage", "That username is taken"))
                }//no else here
                         return;                         

        }else{
            User.findOne({"username" : req.body.username}, function(err,user){
                if(err) return done(err);
                if(user){
                    // arr.push()
                    return done(null, false, req.flash("signupMessage", "That username is taken"))
                }else{
                    var newUser = new User();
                    newUser.username = req.body.username;
                    newUser.password = password;
                    newUser.email = req.body.email;

                    newUser.save(function(err, doc){
                        if(err) throw err;
                        console.log("doc", " " , doc)
                        return done(null, newUser);
                    })                          
                }
            })

        }
    })
    }
))
于 2016-07-26T19:19:14.797 回答
0

试试看:

    var signupMessages = [];
    User.findOne({"email" : email}, function(err, user){
        if(err) return done(err);
        if(user) signupMessages.push("That email is taken");
        User.findOne({"username" : req.body.username}, function(err,user){
                if(err) return done(err);
                if(user) signupMessages.push("That username is taken");
                if(signupMessages.length > 0){
                    return done(null, false, req.flash("signupMessage", signupMessages));
                } else { ...

在这种情况下req.flash("signupMessage")将返回消息数组

于 2016-07-27T05:30:22.767 回答