提问者:小点点

如何根据几次db搜索返回json?


我正在尝试创建一个注册脚本,它检查提交的信息是否已经在数据库中。

这是它的路线

router.post('/', (req, res) => {
let {
    username,
    email,
    password,
    confirm_password
} = req.body;
console.log(req.body);
if (password !== confirm_password) {
    res.status(400).json({msg: "Password does not match."});
    return;
}

 User.findOne({username: username})
    .then(user => {
        console.log(user)
        if (user) {
            res.json({msg: "Username is already taken."})
            return;
        }

    }).catch(err => {console.log(err)});

 User.findOne({email: email})
    .then(user => {
        if (user) {
             res.json({
                msg: "Email is already taken."
            })

        }
    });
let newUser = new User({
    username,
    password,
    email
});
console.log("about to start hash")
return bcrypt.genSalt(10, (err, salt) => {
    if (!err) {
        bcrypt.hash(newUser.password, salt, (err, hash) => {
            if (err) consoloe.log("**********************\n" ,err,"**********************\n");
            newUser.password = hash;
            console.log("before save")
            newUser.save().then(user => {
                console.log("all good")
                res.json({
                    msg:"good"
                });
            });

        })
    }
})

我只是复制了“片段”,如果你注意到未关闭的东西,那就是原因。

我尝试添加这些返回语句,但没有工作,我认为发生这种情况是因为它运行异步,所以它同时做这两件事,这是没有意义的(请解释一下,因为我根本不知道)

它显示的错误是

将标头发送到客户端后,无法对其进行设置

我想要做的是检查用户名和电子邮件是否不存在,在这种情况下,将它们添加到数据库中,并将pass散列(这是可行的,但它忽略了其他条件,所以即使是,它们也会再次添加)

我现在得到的回应是

{“消息”:“用户名已被使用。”}

我想我有的问题是我根本不明白“线程”是如何工作的。


共1个答案

匿名用户

正如您在问题中提到的,findone将异步运行。 您还获得消息的原因是在发送到客户端之后无法设置头,因为您在两个findone方法中都有res.json,并且一旦承诺被解析,两个方法都会尝试发送响应。

您可以简单地通过使用async/await解决此问题,还可以使用$或运算符执行单个查询而不是两个单独的查询

router.post('/', async (req, res) => {

    const user = await User.findOne({$or: [{
        email: email
    }, {
        username: username
    }]});

    if (user) {
        if (user.username === username) {
            res.json({msg: "Username is already taken."})
            return;
        } else {
            res.json({ msg: "Email is already taken."})
            return;
        }
    }   
}