javascript - MongoDB 文档已添加但未在网站上显示(无需刷新)
问题描述
我有一个简单的待办事项列表网站。因此,您可以创建一个待办事项列表,并从列表中添加和删除项目。意思是,有一个List
集合和一个Item
集合,其中 aList
可以有很多Items
内部(项目数组)。我已将 Mongoose (MongoDB) 代码拆分为一个单独的文件 ( model.js
),我的app.js
文件是处理所有 HTTP 请求的地方。导入的所有 Mongoose 方法app.js
都运行良好。问题是当我添加一个Item
到 aList
时,通过按下+
网站上的按钮,它应该在列表中显示新项目。
但是,在我按下+
按钮后,该项目仍然没有显示在列表中。需要刷新网站才能显示。该项目确实已成功添加到数据库中,因为我可以通过控制台日志和检查数据库本身来确认这一点。
该+
按钮触发文件中的app.post('/'...
方法app.js
,以便将项目添加到列表中。
我的下一个方法是使用Promise
该addItemToListInDB
方法(在model.js
文件中),并且使用Async
Await
它可以确保在呈现网页之前将项目添加到数据库中。但是,我对这种方法还有另一个问题。我没有返回更新列表的值(带有新添加的项目),而是[Object Promise]
. 无论如何,Promise
Async
Await
仍然没有解决原来的问题。不确定Promise
在这种情况下是否需要 a 。
请参考我下面的代码(ps为简洁起见,我只包含了文件中的app.get('/'...
(主路由方法)和app.post('/'...
(添加项目方法)app.js
。以及添加项目方法来自model.js
)。
另外,提前为所有控制台日志道歉,但我试图调试这个问题。我不想对 Async Await 的执行顺序感到困惑。
app.js
const express = require('express');
const bodyParser = require('body-parser');
const date = require(`${__dirname}\\date.js`);
const model = require(`${__dirname}\\model.js`);
const ejs = require('ejs');
const _ = require('lodash');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', (req, res) => {
const defaultListName = "Today's";
const todayFormatted = date.getDate();
model.DBUtility.findOneList(defaultListName, (foundList) => {
if (!foundList) {
model.DBUtility.createNewListInDB(defaultListName);
res.redirect('/');
} else {
res.render('list', {
listTitlePassToH1: foundList.name,
todayDate: todayFormatted,
listItems: foundList.items
});
}
});
});
app.post('/', (req, res) => {
const receivedItem = req.body.newItem;
const listName = req.body.listName;
console.log(`before model.DBUtility.addItemToListAndGetUpdatedList(listName, receivedItem)`);
const updatedList = model.DBUtility.addItemToListAndGetUpdatedList(listName, receivedItem);
console.log(`After model.DBUtility.addItemToListAndGetUpdatedList(listName, receivedItem)`);
console.log(`updatedList: ${updatedList}`);
if (listName === "Today's") {
res.redirect('/');
} else {
res.redirect('/' + listName);
}
});
const port = 3000;
app.listen(port, () => {
console.log(`Server started, listening on port: ${port}`);
});
model.js
const mongoose = require('mongoose');
const _ = require("lodash");
//connect to DB
mongoose.connect('mongodb+srv://<username>:<password>.mongodb.net/database', {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false });
//create schema
const itemsSchema = new mongoose.Schema ({
name: String
});
const listSchema = new mongoose.Schema ({
name: String,
items: [itemsSchema]
});
const Item = mongoose.model('Item', itemsSchema);
const List = mongoose.model('List', listSchema);
class DBUtility {
// *** DB utility methods
static addItemToListInDB(listName, itemName) {
return new Promise((resolve, reject) => {
List.findOne({name: listName}, (err, foundList) => {
if (err) {
console.log(err);
reject(err);
} else {
foundList.items.push({ name: itemName });
foundList.save(err => {
if (err) {
console.log(err);
} else {
console.log(`Item ${itemName} added to list ${foundList.name} successfully.`);
resolve(foundList);
}
});
}
});
});
}
static async addItemToListAndGetUpdatedList(listName, itemName) {
try {
const updatedList = await DBUtility.addItemToListInDB(listName, itemName);
console.log(`inside addItemToListAndGetUpdatedList. updatedList ${updatedList}`);
return updatedList;
} catch (err) {
console.log(err);
}
}
}
exports.DBUtility = DBUtility;
终端输出:
Server started, listening on port: 3000
before model.DBUtility.addItemToListAndGetUpdatedList(listName, receivedItem)
After model.DBUtility.addItemToListAndGetUpdatedList(listName, receivedItem)
updatedList: [object Promise]
Item Cheese added to list Shopping successfully.
inside addItemToListAndGetUpdatedList. updatedList {
_id: 5e9cb7b45ceafe2440e09995,
name: 'Shopping',
items: [
{ _id: 5e9cb7c45ceafe2440e09999, name: 'Bread' },
{ _id: 5e9cb7cc5ceafe2440e0999a, name: 'Lemons' },
{ _id: 5e9cb7d25ceafe2440e0999b, name: 'Eggs' },
{ _id: 5e9cb7ea5ceafe2440e0999d, name: 'Butter' },
{ _id: 5e9cbd585ceafe2440e0999e, name: 'Cheese' }
],
__v: 6
}
有一件事要提,我希望这不是红鲱鱼,当我在我的计算机上本地托管 MongoDB 时,我不记得有这个问题。但是当我迁移到 MongoDB Atlas 云托管时,问题似乎开始出现了。
解决方案
为什么你有错误:
您遇到此错误是因为在 post 请求处理程序中,更新 List 集合(model.DBUtility.addItemToListAndGetUpdatedList()
)的 db 操作是异步的,即它直到将来某个较晚时间才完成,因此,重定向响应在更新到 List 之前发送收集完成。
修复:
要解决此问题,您需要确保仅在更新操作完成后才发送重定向响应。您可以使用async/await
.
使 post 请求处理程序成为一个async
函数和await
db 操作以更新列表
// Note the async keyword used before the request handler function
app.post('/', async (req, res) => {
const receivedItem = req.body.newItem;
const listName = req.body.listName;
// The await keyword below ensures the update operation completes
// before moving to the next statement
const updatedList = await model.DBUtility.addItemToListAndGetUpdatedList(listName, receivedItem);
if (listName === "Today's") {
res.redirect('/');
} else {
res.redirect('/' + listName);
}
});
这样,重定向响应只会在 List 集合的更新完成后发送。
要注意的另一件事是 db update 操作可能会引发错误,因此您可能需要考虑将model.DBUtility.addItemToListAndGetUpdatedList()
方法调用包装在 a 中try/catch
并处理任何潜在的错误。
推荐阅读
- vue.js - Vue js项目未加载.env变量
- java - 尝试使用 api 包装器时 gradle 出现 NoClassDeffFound 错误
- ios - 如何使用 iOS 客户端证书身份验证执行 HTTP 请求
- purescript - 如何将 Purescript 翻译成 ES6
- javascript - 无法将 Json 数据从 Ajax 发送到 Servlet
- python - macOS 11 Big Sur 附带了哪些版本的 Python?
- mongodb - Mongodb 在聚合查询中使用 $text
- sorting - 这个汇编代码是否按升序排序数字?
- jmeter - 取消应用程序中的活动不起作用-Jmeter
- c++ - 对于循环 C++ 可能效率低下