我正在尝试创建一个注册脚本,它检查提交的信息是否已经在数据库中。
这是它的路线
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散列(这是可行的,但它忽略了其他条件,所以即使是,它们也会再次添加)
我现在得到的回应是
{“消息”:“用户名已被使用。”}
我想我有的问题是我根本不明白“线程”是如何工作的。
正如您在问题中提到的,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;
}
}
}