Mongoose中Model.find()不再支持回调函数的问题求助
解决Mongoose "Model.find() no longer accepts a callback" 报错问题
问题描述
跟着Angela Yu的课程学Mongoose做待办清单应用,但Mongoose更新后,find这类函数不再支持回调参数,抛出错误:Model.find() no longer accepts a callback in Mongoose。我需要把所有列表项渲染到页面上,作为新手找不到替代方案。
原JavaScript代码
const express = require("express"); const bodyParser = require("body-parser"); const mongoose = require("mongoose"); const app = express(); var items = []; app.set("view engine", "ejs"); app.use(bodyParser.urlencoded({extended: true})); mongoose.connect("mongodb://localhost:27017/todoList", {useNewUrlParser: true}); const ItemSchema = new mongoose.Schema({ name: String }); const Item = mongoose.model("Item", ItemSchema); // Items = collection name & ItemScema = Schema //Some Default Items for the list const Item1 = new Item({ name: "Welcome To Your To-Do-List!" }) const Item2 = new Item({ name: "Hit the + button to add a new Item" }) const Item3 = new Item({ name: "<-- Hit this to delete an item" }) const defaultItems = [Item1, Item2, Item3]; app.get("/", function (req, res) { var today = new Date(); var options = { weekday: "long", day: "numeric", year: "numeric" , month: "numeric" }; var day = today.toLocaleDateString("en-GB", options); Item.find({}, function(err, FoundItems){ console.log(FoundItems); res.render("list", {kindOfDay: day, newItem: FoundItems}); }) }); app.post("/", function(req, res){ var item = req.body.newItem; items.push(item); res.redirect("/"); }) app.listen(3000, function () { //or process.env.PORT || 2000 console.log("Server started on port 3000"); })
原EJS代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>To Do List </title> <link rel = "stylesheet" href = "css/styles.css"> </head> <body> <h1> <%= kindOfDay%></h1> <ul> <li>Buy Food</li> <li>Cook Food</li> <li>Eat Food</li> <%for (var i = 0; i < newItem.length; i++){ %> <li><%= newItem[i] %></li> <% } %> </ul> <form class="" action = "/" method = "post"> <input type = "text" name = "newItem"> <button type = "submit" name = "button">Add</button> </form> </body> </html>
解决方案
核心原因
Mongoose 6.x及以上版本彻底移除了对回调函数的支持,所有数据库异步操作必须使用Promise链式调用或async/await语法,这里推荐用async/await,更符合新手阅读习惯。
1. 重构app.get("/")的数据库查询逻辑
把原来的回调写法改成async/await,同时补上数据库为空时插入默认数据的逻辑(避免每次重启服务器重复插入):
app.get("/", async function (req, res) { var today = new Date(); var options = { weekday: "long", day: "numeric", year: "numeric" , month: "numeric" }; var day = today.toLocaleDateString("en-GB", options); try { // 查询所有列表项 const FoundItems = await Item.find({}); console.log(FoundItems); // 如果数据库为空,插入默认数据 if (FoundItems.length === 0) { await Item.insertMany(defaultItems); console.log("默认数据已插入数据库"); // 插入后重新查询最新数据 const updatedItems = await Item.find({}); res.render("list", {kindOfDay: day, newItem: updatedItems}); } else { // 直接渲染已有数据 res.render("list", {kindOfDay: day, newItem: FoundItems}); } } catch (err) { // 捕获并打印错误,给前端返回错误信息 console.error("查询数据出错:", err); res.status(500).send("加载待办清单失败,请稍后重试"); } });
2. 修复POST请求的数据库保存逻辑
原来的POST请求只是把新项推到本地数组,没有保存到数据库,修改后将新项存入MongoDB:
app.post("/", async function(req, res){ const itemName = req.body.newItem; // 创建新的Item实例 const newItem = new Item({ name: itemName }); try { // 保存到数据库 await newItem.save(); console.log("新项已添加"); // 重定向回首页刷新列表 res.redirect("/"); } catch (err) { console.error("添加新项出错:", err); res.status(500).send("添加待办项失败,请稍后重试"); } });
3. 修正EJS的渲染错误
原来的EJS直接输出newItem[i]会显示整个Item对象,需要提取name属性才能显示正确的待办文本:
<ul> <li>Buy Food</li> <li>Cook Food</li> <li>Eat Food</li> <%for (var i = 0; i < newItem.length; i++){ %> <!-- 修改这里,显示对象的name属性 --> <li><%= newItem[i].name %></li> <% } %> </ul>
完整修改后的JavaScript代码
const express = require("express"); const bodyParser = require("body-parser"); const mongoose = require("mongoose"); const app = express(); app.set("view engine", "ejs"); app.use(bodyParser.urlencoded({extended: true})); // 连接数据库,加上useUnifiedTopology: true避免版本警告 mongoose.connect("mongodb://localhost:27017/todoList", {useNewUrlParser: true, useUnifiedTopology: true}); const ItemSchema = new mongoose.Schema({ name: String }); const Item = mongoose.model("Item", ItemSchema); // 默认待办项 const Item1 = new Item({ name: "Welcome To Your To-Do-List!" }) const Item2 = new Item({ name: "Hit the + button to add a new Item" }) const Item3 = new Item({ name: "<-- Hit this to delete an item" }) const defaultItems = [Item1, Item2, Item3]; app.get("/", async function (req, res) { var today = new Date(); var options = { weekday: "long", day: "numeric", year: "numeric" , month: "numeric" }; var day = today.toLocaleDateString("en-GB", options); try { const FoundItems = await Item.find({}); if (FoundItems.length === 0) { await Item.insertMany(defaultItems); console.log("默认数据已插入"); const updatedItems = await Item.find({}); res.render("list", {kindOfDay: day, newItem: updatedItems}); } else { res.render("list", {kindOfDay: day, newItem: FoundItems}); } } catch (err) { console.error(err); res.status(500).send("加载失败"); } }); app.post("/", async function(req, res){ const itemName = req.body.newItem; const newItem = new Item({name: itemName}); try { await newItem.save(); res.redirect("/"); } catch (err) { console.error(err); res.status(500).send("添加失败"); } }); app.listen(3000, function () { console.log("Server started on port 3000"); })
内容的提问来源于stack exchange,提问作者Aryan Sharma
相关产品推荐
相关产品推荐

