为何这段代码中的Mongoose查询执行后返回undefined?
问题原因
- 作用域冲突:你在全局作用域用
var list = new Array()声明了变量,但是在findMany的回调内部又用let list重新声明了同名的块级作用域变量,内部的变量只会在回调函数范围内生效,完全不会修改外层的list变量,所以外层访问的还是初始未被赋值的list。 - 异步执行顺序问题:mongoose的数据库查询是异步IO操作,你调用
db.findMany之后,主线程不会等待回调执行完成,会直接继续往下执行外层的console.log,此时回调还没被触发,哪怕你没有重复声明变量,外层的list也还没被赋值,一样拿不到正确结果。
修复方案
方案1:保留回调写法,调整作用域和逻辑位置
不要在回调内部重复声明list,同时把所有需要用到list的逻辑都放到回调内部执行:
var list = new Array(); db.findMany(Scholarship, {}, {scholarship_type:1, _id:0}, function (resultArray) { // 直接给外层list赋值,不要加let重新声明 list = resultArray.map(scholarship => scholarship.scholarship_type); console.log(list.toString()); // 所有用到list的逻辑都放在这里调用 handleListResult(list); }); function handleListResult(list) { // 在这里写后续处理逻辑 console.log('处理list:', list.toString()); }
方案2:改造成async/await写法(更推荐,避免回调地狱)
先修改你封装的findMany方法,让它返回Promise:
/* searches for multiple documents based on the model `model` filtered through the object `query` limits the fields returned based on the string `projection` */ findMany: function (model, query, projection) { // 直接返回mongoose查询的Promise实例 return model.find(query, projection).exec(); },
调用时用async/await语法同步化异步逻辑:
async function fetchScholarshipTypes() { try { const resultArray = await db.findMany(Scholarship, {}, {scholarship_type:1, _id:0}); const list = resultArray.map(scholarship => scholarship.scholarship_type); // 这里可以正常使用list console.log(list.toString()); return list; } catch (err) { console.error('查询出错:', err); return []; } } // 调用异步函数获取结果 fetchScholarshipTypes().then(list => { console.log('外层获取到的list:', list.toString()); })
内容的提问来源于stack exchange,提问作者Rollo
相关产品推荐
相关产品推荐

