新手技术求助:使用Mongoose操作MongoDB查询并随机打印条目
解决Mongoose异步查询结果返回及随机选取记录问题
问题根源
getWords无法返回结果:Card.find是异步操作,回调函数内的return results无法将结果传递给外层函数的调用者,且原getWords本身没有返回值,导致调用时得到undefined。result.length报错:因为result是undefined,访问其length属性会触发错误;同时调用getWord()时未传入ctgry参数,会导致查询条件无效。
解决方案
使用async/await处理异步操作,这是处理Mongoose异步查询最直观的方式:
1. 修改getWords为异步函数,正确获取查询结果
async function getWords(ctgry ) { // 校验分类参数是否传入 if (!ctgry) { throw new Error("请传入分类参数"); } try { // 用await等待异步查询完成,直接拿到结果 const results = await Card.find({"category" : ctgry }); return results; } catch (err) { console.error("查询数据库失败:", err); throw err; // 抛出错误让调用者处理 } };
2. 修改getWord为异步函数,等待查询结果后随机选取
async function getWord( ctgry ) { // 等待getWords返回的查询结果 const result = await getWords( ctgry ); // 处理分类下无数据的情况 if (result.length === 0) { throw new Error(`分类${ctgry}下没有找到记录`); } const num = getRandomInt(0, result.length); return result[num]; };
3. 正确调用异步函数
异步函数返回的是Promise对象,需要用.then或异步自执行函数处理结果:
// 方式1:使用.then链式调用 getWord("你的分类值") // 替换为实际的category值 .then(randomCard => { console.log("Sample text: " + randomCard.word); // 拼接需要的字段,比如word }) .catch(error => { console.error("获取随机记录失败:", error.message); }); // 方式2:用异步立即执行函数(更直观) (async () => { try { const randomCard = await getWord("日常用语"); // 替换为实际分类值 console.log("Sample text: " + randomCard.word); } catch (error) { console.error(error.message); } })();
完整修改后代码
//Connecting To DB const mongoose = require('mongoose'); const db = mongoose.connection; const host = process.env.host; console.log(host) const dbupdate = { useNewUrlParser : true, useUnifiedTopology : true }; mongoose.connect(host, dbupdate); db.on('error', (err) => console.log('Error, DB not connected')); db.on('connected', () => console.log('connected to mongo')); db.on('disconnected', () => console.log('Mongo is disconnected')); db.on('open', () => console.log('Connection Made!')); const Schema= mongoose.Schema; const cardSchema = new Schema({ word: String, visual : String, category : String }); const Card = mongoose.model('expressions', cardSchema ); async function getWords(ctgry ) { if (!ctgry) { throw new Error("请传入分类参数"); } try { const results = await Card.find({"category" : ctgry }); return results; } catch (err) { console.error("查询数据库失败:", err); throw err; } }; function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min) + min); }; async function getWord( ctgry ) { const result = await getWords( ctgry ); if (result.length === 0) { throw new Error(`分类${ctgry}下没有找到记录`); } const num = getRandomInt(0, result.length); return result[num]; }; // 调用示例,替换为实际分类值 (async () => { try { const randomCard = await getWord("日常用语"); console.log("Sample text: " + randomCard.word); } catch (error) { console.error(error.message); } })();
内容的提问来源于stack exchange,提问作者Michael Walker
相关产品推荐
相关产品推荐

