Node.js中在forEach循环执行Mongoose查询返回空数组怎么解决
问题原因
Array.prototype.forEach 不支持等待异步函数执行完成,你传入的async回调执行后返回的Promise不会被等待,所以代码走到console.log和res.render的时候,所有findOne的数据库查询还没执行完,categoryClasses自然是空数组。
修复方案
把forEach换成map配合Promise.all,等待所有异步查询完成后再往下执行,修改后的代码如下:
app.get('/', async (req, res) => { const descriptions = await Description.find({}); let tempDescriptions = []; descriptions.forEach(element => tempDescriptions.push(...element.category)); const categories = [...new Set(tempDescriptions)] // 用map把每个查询转为Promise,再用Promise.all等待所有完成 const categoryClasses = await Promise.all( categories.map(async (element) => { const description = await Description.findOne({category : element}); // 建议补充判空逻辑,避免description为空时报错 return description?.category?.[0]; }) ); console.log(categoryClasses); res.render('home', { categories, categoryClasses }) });
额外优化建议
- 当前实现会先查全量
Description,再对每个分类单独发起一次数据库查询,请求量较高。如果数据量较大,可以直接用MongoDB的聚合查询一步拿到去重分类和对应分类的首条属性,大幅减少数据库请求次数。
内容的提问来源于stack exchange,提问作者novicecoder
相关产品推荐
相关产品推荐

