我正试图找到我的用户正在收听的所有音乐。我是这样做的:
User.find().exec((err, users) => {
users.forEach((user, index) => {
Musics.count({ idReader: user._id }, (err, count) => {
result.push({ mail: user.mail, count: count });
if (index >= users.length - 1) {
return res.json(result);
}
});
});
});
它有效但不是每次都有效。有时我只有30%的用户有时100%。我认为这是因为异步。但我不知道如何做不同的事情。谢谢!
答案 0 :(得分:1)
你的直觉是正确的。在forEach
循环中,您为每个用户进行计数查询,并且在按顺序发出请求时,它们不一定按顺序解析。这就是为什么检查index
不值得信赖的原因。这是一个应该成为它的片段:
User.find().exec((err, users) => {
// get an array of promises for each count query
var promises = users.map(user =>
Musics.count({ idReader: user._id })
// format ther result
.then(count => ({
mail: user.mail,
count: count
}))
);
// after each request to the db is ready
Promise.all(promises)
.then(result => {
res.json(result)
})
.catch( err => {
console.log(err)
res.status(500).send('Something went wrong')
})
});
答案 1 :(得分:0)
你必须使用承诺来获得确切的结果。
musicListeners = async (req, res) => {
try {
const users = await Users.find({})
try {
const userPromises = [];
for (let user in users)
userPromises.push(Music.count({ idReader: user._id }))
Promise.all(userPromises).then(res => {
return res.send(res)
}, err => {
return res.status(500).send(err)
})
} catch (error) {
return res.status(500).send('Something went wrong')
}
} catch (error) {
return res.status(500).send('Something went wrong')
}
}
Async / Await是编写好代码的好方法,但需要节点版本到LTS 1。它不适用于6.节点。