我正在用node.js, express, mongodb, express session等做一个简单的项目。这是一个旅游类型的网站,数据库中的用户有用户名、密码和他想去的目的地列表。每个目的地页面都有一个按钮,用于将该目的地添加到列表中,还有一个页面显示当前用户的列表。正确的功能是,在按下第一个按钮时,目的地应该被添加到数据库中的用户列表中,并且列表页面的ejs视图应该被更新,在按下第二个按钮时,应该出现一个警告,表明当前目的地已经在用户列表中。然而,看似随机的是,按钮有时只在按下两次按钮后才正常工作,而列表页面的警报和ejs视图更新发生在按下第三次按钮时。下面是一些代码片段:
这是我对列表页面的get请求,我将当前会话用户的想要的列表作为参数传递:
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else res.redirect('/');
}
app.get('/wanttogo',isAuthenticated,function(req,res){
res.render('wanttogo',{dests:req.session.user.wantgo})
});
在每个页面的post请求中,我在会话和数据库中更新这个列表。以下是其中一个页面的示例:
app.post('/inca',function(req,res){
if((req.session.user.wantgo.length === 0) || !(req.session.user.wantgo.includes("Inca Trail to Machu Picchu"))){
req.session.user.wantgo.push("Inca Trail to Machu Picchu");
req.session.save();
db.collection("myCollection").updateOne({username:req.session.user.username},{$set:{wantgo:req.session.user.wantgo}});
db.collection("myCollection").findOne({username: req.session.user.username},(err,result)=>{
req.session.user.wantgo = result.wantgo;
req.session.user=result;
req.session.save();
});
}
else{
alert('This destination is already on your Want-To-Go List');
}
res.redirect('/inca');
,这是列表页面ejs视图的一部分,我循环遍历用户列表,并使用我之前传递的参数打印它:
<div>
<% for(var i=0; i < dests.length; i++) { %>
<h1><%= dests[i] %></h1>
<% } %>
</div>
任何帮助都是感激的!
这可能是由于"updateOne"one_answers";findOne"是异步函数,因此在按第二次按钮之前数据库不会更新。
由于这取决于异步操作完成的时间,因此有时有效,有时不有效。
试试这样使用async await
app.post('/inca',async function(req,res){
if((req.session.user.wantgo.length === 0) || !(req.session.user.wantgo.includes("Inca Trail to Machu Picchu"))){
req.session.user.wantgo.push("Inca Trail to Machu Picchu");
req.session.save();
await db.collection("myCollection").updateOne({username:req.session.user.username},{$set:{wantgo:req.session.user.wantgo}});
await db.collection("myCollection").findOne({username: req.session.user.username},(err,result)=>{
req.session.user.wantgo = result.wantgo;
req.session.user=result;
req.session.save();
});
}
else{
alert('This destination is already on your Want-To-Go List');
}
res.redirect('/inca');