postsArr
没有得到数据
router.get('/user-post/:id', checkJwt, (req, res, next) => {
let postsArr = []
db.userSchema.findOne({ _id: req.params.id })
.populate('posts')
.exec((err, da) => {
for (let i = 0; i < da.posts.length; i++) {
db.postSchema.find({ _id: da.posts[i]._id })
.populate('comments')
.exec((err, post) => {
postsArr.push(post)
})
}
console.log(postsArr)
})
})
如果您在数据库上使用 promise 接口,这会容易得多:
router.get('/user-post/:id', checkJwt, async (req, res, next) => {
try {
let da = await db.userSchema.findOne({ _id: req.params.id }).populate('posts').exec();
let postsArray = await Promise.all(da.posts.map(post => {
return db.postSchema.find({ _id: post._id }).populate('comments').exec();
}));
res.json(postsArray);
} catch (e) {
console.log(e);
res.sendStatus(500):
}
});
循环中异步操作的挑战在于它们不是按顺序运行的——它们都是并行运行的。该for
循环刚刚起步所有的异步操作,然后你永远不知道,当他们完成所有的工作,除非你跟踪他们都弄好了。这可以通过使用计数器来跟踪每个异步结果何时完成而无需承诺即可完成,但是让Promise.all()
您为您完成要容易得多。它还会将所有结果按正确顺序排列。
如果您想对数据库操作进行排序并一次一个地连续运行它们,您可以这样做:
router.get('/user-post/:id', checkJwt, async (req, res, next) => {
try {
let da = await db.userSchema.findOne({ _id: req.params.id }).populate('posts').exec();
let postsArray = [];
for (let post of da.posts) {
let result = await db.postSchema.find({ _id: post._id }).populate('comments').exec();
postsArray.push(result);
}
res.json(postsArray);
} catch (e) {
console.log(e);
res.sendStatus(500):
}
});
第二个版本一次只运行一个数据库操作,顺序。它将减少数据库的峰值负载,但完成速度可能会更慢。
您会注意到使用 Promiseawait
并使错误处理变得更加简单,因为所有错误都将传播到try/catch
您可以记录错误并发送错误响应的相同位置。您的原始代码没有对您的数据库调用进行错误处理。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句