Mongoose报错:Model.find()不再支持回调函数,请求排查解决
问题原因与解决方案
报错Model.find() no longer accept a call back是因为你使用的Mongoose版本为6.x及以上,该版本已彻底移除了对CRUD方法回调函数的支持,所有查询操作现在仅返回Promise对象,不再接受回调参数。
你需要把代码中所有用回调的Mongoose操作改成async/await语法,以下是修改后的完整代码:
//jshint esversion:6 const express = require("express"); const bodyParser = require("body-parser"); const mongoose = require("mongoose"); const _ = require("lodash"); const app = express(); app.set('view engine', 'ejs'); app.use(bodyParser.urlencoded({extended: true})); app.use(express.static("public")); // 连接MongoDB,新版本无需额外配置参数,用Promise处理连接结果 mongoose.connect("mongodb://localhost:27017/todolistDB") .then(() => console.log("成功连接MongoDB")) .catch(err => console.log("MongoDB连接失败:", err)); const itemsSchema = { name: String }; const Item = mongoose.model("Item", itemsSchema); const item1 = new Item({ name: "Welcome to your todolist!" }); 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]; const listSchema = { name: String, items: [itemsSchema] }; const List = mongoose.model("List", listSchema); // 首页路由:改用async/await app.get("/", async function(req, res) { try { const foundItems = await Item.find({}); if (foundItems.length === 0) { await Item.insertMany(defaultItems); console.log("Successfully saved default items to DB."); res.redirect("/"); } else { res.render("list", {listTitle: "Today", newListItems: foundItems}); } } catch (err) { console.log("获取数据失败:", err); res.status(500).send("服务器内部错误"); } }); // 自定义列表路由:改用async/await app.get("/:customListName", async function(req, res){ const customListName = _.capitalize(req.params.customListName); try { const foundList = await List.findOne({name: customListName}); if (!foundList){ // 创建新列表 const list = new List({ name: customListName, items: defaultItems }); await list.save(); res.redirect("/" + customListName); } else { // 展示已有列表 res.render("list", {listTitle: foundList.name, newListItems: foundList.items}); } } catch (err) { console.log("访问自定义列表失败:", err); res.status(500).send("服务器内部错误"); } }); // 添加项路由:改用async/await app.post("/", async function(req, res){ const itemName = req.body.newItem; const listName = req.body.list; const item = new Item({ name: itemName }); try { if (listName === "Today"){ await item.save(); res.redirect("/"); } else { const foundList = await List.findOne({name: listName}); foundList.items.push(item); await foundList.save(); res.redirect("/" + listName); } } catch (err) { console.log("添加项失败:", err); res.status(500).send("服务器内部错误"); } }); // 删除项路由:改用async/await app.post("/delete", async function(req, res){ const checkedItemId = req.body.checkbox; const listName = req.body.listName; try { if (listName === "Today") { await Item.findByIdAndRemove(checkedItemId); console.log("Successfully deleted checked item."); res.redirect("/"); } else { await List.findOneAndUpdate({name: listName}, {$pull: {items: {_id: checkedItemId}}}); res.redirect("/" + listName); } } catch (err) { console.log("删除项失败:", err); res.status(500).send("服务器内部错误"); } }); app.get("/about", function(req, res){ res.render("about"); }); app.listen(3000, function() { console.log("Server started on port 3000"); });
关键修改点说明
- 所有Mongoose查询操作(
find、findOne、insertMany、save、findByIdAndRemove、findOneAndUpdate)都改用async/await语法包裹,并通过try/catch捕获错误 - MongoDB连接部分改用Promise的
then/catch处理连接状态,移除了过时的useNewUrlParser配置(新版本已默认启用) - 保留了原有业务逻辑,仅替换了异步操作的写法
内容的提问来源于stack exchange,提问作者Aman Sharma
相关产品推荐
相关产品推荐

