Javascript 通过express从mongo获取数据、构建对象并发送到React
我现在被困在地狱里。 在React中,我有一个页面/菜单,可以通过ExpressJSAPI从我的mongo实例加载数据 在我的名为“菜单”的数据库中,我有代表膳食类型的集合,如“早餐”、“午餐”等。在这些集合中,每个项目的文档都类似于以下面包集合示例:Javascript 通过express从mongo获取数据、构建对象并发送到React,javascript,node.js,reactjs,mongodb,express,Javascript,Node.js,Reactjs,Mongodb,Express,我现在被困在地狱里。 在React中,我有一个页面/菜单,可以通过ExpressJSAPI从我的mongo实例加载数据 在我的名为“菜单”的数据库中,我有代表膳食类型的集合,如“早餐”、“午餐”等。在这些集合中,每个项目的文档都类似于以下面包集合示例: { _id: 2398jcs9dn2f9f, name: "Ciabatta", desc: "Italian bread", imageURI: "image01.jpg&quo
{
_id: 2398jcs9dn2f9f,
name: "Ciabatta",
desc: "Italian bread",
imageURI: "image01.jpg",
reviews: []
}
这是我的api,当页面加载时将调用它
exports.getAllFoods = (req, res, next) => {
const db = mongoose.connection
const allCollections = {}
try {
db.db.listCollections().toArray((err, collections) => {
collections.forEach((k) => {
allCollections[k.name] = []
})
Object.keys(allCollections).map(k => {
let Meal = mongoose.model(k, MealSchema)
meal = Meal.find((err, docs) => {
allCollections[k] = docs
console.log(allCollections)
})
})
res.send(allCollections)
})
} catch (error) {
console.log(error)
res.send('unable to get all collections')
}
}
console.log(allCollections)的最后一个输出生成以下内容:
{ snacks:
[ { review: [],
tags: [],
_id: 5fcec3fc4bc5d81917c9c1fe,
name: 'Simosa',
description: 'Indian food',
imageURI: 'image02.jpg',
__v: 0 } ],
breads:
[ { review: [],
tags: [],
_id: 5fcec41a4bc5d81917c9c1ff,
name: 'Ciabatta',
description: 'Italian bread',
imageURI: 'image02.jpg',
__v: 0 } ],
}
这正是我所需要的,但我一直在思考如何发送邮件以作出反应。我该如何发送上述json?res.send(allCollections)为我提供了以下信息:
{
"snacks": [],
"breads": [],
"drinks": []
}
我理解为什么会发送上述信息,但我不知道我需要做些什么来解决它
这是我对页面加载的反应
useEffect(() => {
axios
.get('http://localhost:8888/api/allFoods')
.then((res) => {
setMealTypes(res.data)
})
.catch((err) => [
console.log(err)
])
}, [])
最终,我需要在控制台中输出json,因为我希望循环遍历该数据并使用该键作为标题,然后列出值数组中的值
<div>
<h2>Breads</h2>
<img src=image01.jpg/>
<h3>Ciabatta</h3>
<p>Italian bread</p>
...
</div>
...
面包
西亚巴塔
意大利面包
...
...
我非常感谢任何帮助,以及我应该阅读的任何文档,以帮助和提高我对javascript的理解我希望这将对您有所帮助:在从express api发送集合之前,您需要首先使用stringify方法,然后在React前端使用JSON.parse来恢复对象。
PS:您能在res.send(allCollections)上方一行执行console.log(allCollections)吗?您需要以JSON格式将其发送到前端
将
res.send(allCollections)
替换为res.json(allCollections)
我更喜欢使用async
/wait
和Promise.all
,替换大多数回调
因为在遍历数组时调用DB,所以有一种最烦人的回调情况:如何发出一堆异步消息,然后再得到结果?在发送结果之前,您需要一些其他的东西来确保调用所有回调
Async/await意味着我们可以声明函数是异步的,并等待异步操作的结果。async/await在JS中很烦人,因为它抽象掉回调,实际上在下面创建了一个承诺。使事情进一步复杂化的是,async/await不能解决发出多个异步函数的问题,因此我们必须再次依赖这个奇特的Promise.all()
函数与map
-将所需的输入数组映射为异步函数
原件:
Object.keys(所有集合).map(k=>{
让膳食=猫鼬。模型(k,MealSchema)
膳食=膳食。查找((错误,文档)=>{
所有集合[k]=单据
console.log(所有集合)
})
});
建议异步/等待:
wait Promise.all(Object.key(allCollections.map)(异步k=>{
让膳食=猫鼬。模型(k,MealSchema)
let docs=等待用餐。find();
所有集合[k]=单据;
console.log(所有集合);
}));
另一个优点是错误处理。如果在原始示例的回调中发生任何错误,它们将不会被捕获在此try/catch块中。
async/await会像您预期的那样处理错误,错误最终会出现在catch块中
。。。
//现在我们已经等待了上面所有的异步调用,应该在异步调用之后而不是之前执行。
res.send(所有集合);
})
}捕获(错误){
console.log(错误)
res.send('无法获取所有集合')
}
}
从技术上讲,Promise.all()
返回一个结果数组,但是我们可以忽略它,因为您正在格式化一个对象
这方面还有很多进一步优化的空间。我可以将整个函数编写为:
exports.getAllFoods=async(请求、回复、下一步)=>{
const db=mongoose.connection.db;
试一试{
let collections=wait db.listCollections().toArray();
让所有集合={};
集合。forEach((k)=>{
所有集合[k.name]=[];
})
//对于每个集合键名称,从数据库中查找文档
//在继续下一个块之前,等待此块完成
等待Promise.all(Object.keys(allCollections.map)(异步k=>{
让膳食=猫鼬。模型(k,MealSchema)
let docs=等待用餐。find();
所有集合[k]=单据;
}));
//如果未发生错误,则应填充所有集合
console.log(所有集合);
res.send(所有集合);
}捕获(错误){
console.log(错误)
res.send('无法获取所有集合')
}
}
完全未经测试
您可能会发现这些链接比我的解释更有帮助:
非常感谢。这解决了我的问题。正如您所说,这允许在发送我的请求之前完成所有回调。非常感谢。为了更好地理解async/await,我将浏览这些资源