使用Mongoose无模型无架构从MongoDB取数未获预期输出
问题:Mongoose连接MongoDB后无法获取集合数据
我编写了如下代码,试图在不使用模型和架构的情况下,通过Mongoose从MongoDB中获取数据,代码中已替换真实密码。已确认Mongoose成功连接MongoDB,但未得到预期输出。
代码
const mongoose = require('mongoose'); const mongoURI = 'mongodb+srv://choudharykamal620:<password>@cluster0.i9h833n.mongodb.net/gofoodmern?retryWrites=true&w=majority'; const mongoDB = async () => { await mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => { console.log('connected to MongoDB'); const fetched_data = mongoose.connection.db.collection("food_items"); console.log("1") fetched_data.find({}).toArray(function (err, data) { console.log("2"); if (err) console.log(err); else console.log(data); console.log("3"); }) }) .catch((error) => { console.error('Error connecting to MongoDB: ', error); }) console.log("4"); }; module.exports = mongoDB;
实际输出
connected to MongoDB 1 4
预期输出
connected to MongoDB 1 2 获取到的文档 3 4
解决方案
问题根源是你混用了async/await和.then(),且toArray是异步操作,原代码中console.log("4")会在toArray的回调触发前执行,导致输出顺序不符合预期。以下是两种修复方案:
方案1:用async/await统一处理异步逻辑(推荐)
const mongoose = require('mongoose'); const mongoURI = 'mongodb+srv://choudharykamal620:<password>@cluster0.i9h833n.mongodb.net/gofoodmern?retryWrites=true&w=majority'; const mongoDB = async () => { try { // 等待连接完成 await mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true }); console.log('connected to MongoDB'); const fetched_data = mongoose.connection.db.collection("food_items"); console.log("1"); // 等待toArray异步操作完成,获取数据 const data = await fetched_data.find({}).toArray(); console.log("2"); console.log(data); console.log("3"); } catch (error) { console.error('Error connecting to MongoDB: ', error); } console.log("4"); }; module.exports = mongoDB;
方案2:保持回调风格,调整执行顺序
const mongoose = require('mongoose'); const mongoURI = 'mongodb+srv://choudharykamal620:<password>@cluster0.i9h833n.mongodb.net/gofoodmern?retryWrites=true&w=majority'; const mongoDB = () => { mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => { console.log('connected to MongoDB'); const fetched_data = mongoose.connection.db.collection("food_items"); console.log("1"); fetched_data.find({}).toArray(function (err, data) { console.log("2"); if (err) console.log(err); else console.log(data); console.log("3"); // 确保数据获取完成后再输出4 console.log("4"); }); }) .catch((error) => { console.error('Error connecting to MongoDB: ', error); console.log("4"); }); }; module.exports = mongoDB;
说明
- 原代码中,
toArray的回调函数会在后续事件循环阶段执行,而console.log("4")是同步执行的,所以会先输出4,之后才会触发回调里的内容。 - 方案1用
async/await让异步操作按顺序执行,代码更清晰易维护;方案2将console.log("4")移到回调内部,保证在数据获取完成后再执行。
内容的提问来源于stack exchange,提问作者Kamal Choudhary
相关产品推荐
相关产品推荐

