奇怪的异步node.js

问题描述 投票:1回答:2

我正试图找到我的用户正在收听的所有音乐。我是这样做的:

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%。我认为这是因为异步。但我不知道如何做不同的事情。谢谢 !

javascript node.js asynchronous mongoose
2个回答
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')
        })
});

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的好方法。它不适用于6.节点。

© www.soinside.com 2019 - 2024. All rights reserved.