在Node.js中使用Mongoose全局访问MongoDB数据遇阻
问题原因分析
你的代码出现food_items为空的问题,核心是异步时序+变量导出方式导致的:
- 模块加载时序问题:Node.js模块是同步加载的,当
routes.js导入mongoose.js时,mongoose.connect和后续的数据查询还处于异步等待状态,此时food_items还是初始的undefined,导出的对象里的food_items就是这个值。 - 导出值的不可更新性:你直接导出
{ food_items }时,相当于创建了一个包含当前food_items值的新对象,后续异步操作中给原变量food_items赋值,不会同步到导出对象的属性上——它们是两个独立的内存值,而非引用关联。
解决方案
方案一:用异步函数封装数据获取(适配原有直接操作集合的方式)
修改mongoose.js,通过异步函数确保获取到已加载完成的数据:
const mongoose = require('mongoose'); const mongouri = "mongodb://127.0.0.1:27017/Foodb"; let food_items; // 封装异步加载函数,支持复用缓存 const getFoodItems = async () => { if (food_items) return food_items; // 已加载过直接返回缓存 try { await mongoose.connect(mongouri); console.log('Connected to database successfully'); const foodItemsCollection = mongoose.connection.db.collection("FoodItems"); food_items = await foodItemsCollection.find({}).toArray(); return food_items; } catch (error) { console.error('Error loading food items:', error); throw error; } }; module.exports = { getFoodItems };
修改routes.js,调用异步函数获取数据:
const router = require('express').Router(); const { getFoodItems } = require('../config/mongoose'); router.post('/foodata', async (req, res) => { try { const food_items = await getFoodItems(); res.send({ food_items }); console.log(food_items); } catch (err) { console.error(err); res.status(500).send({ error: 'Failed to load food data' }); } }); module.exports = router;
方案二:使用Mongoose模型(更符合Mongoose最佳实践)
放弃直接操作集合,用Mongoose的Schema和模型来管理数据,这也是Mongoose设计的初衷:
修改mongoose.js,定义模型并导出:
const mongoose = require('mongoose'); const mongouri = "mongodb://127.0.0.1:27017/Foodb"; // 定义集合对应的Schema(根据你的实际字段调整) const foodItemSchema = new mongoose.Schema({ name: String, price: Number, category: String }); // 创建模型,第三个参数指定集合名(避免Mongoose自动复数化) const FoodItem = mongoose.model('FoodItem', foodItemSchema, 'FoodItems'); // 数据库连接 mongoose.connect(mongouri) .then(() => console.log('Connected to database successfully')) .catch(err => console.error('Error connecting to database:', err)); module.exports = { FoodItem };
修改routes.js,直接通过模型查询数据:
const router = require('express').Router(); const { FoodItem } = require('../config/mongoose'); router.post('/foodata', async (req, res) => { try { const food_items = await FoodItem.find({}); res.send({ food_items }); console.log(food_items); } catch (err) { console.error(err); res.status(500).send({ error: 'Failed to load food data' }); } }); module.exports = router;
内容的提问来源于stack exchange,提问作者Abdul Azeez
相关产品推荐
相关产品推荐

