【问题标题】:Wierd async node.js奇怪的异步 node.js
【发布时间】:2018-08-14 05:55:53
【问题描述】:

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

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

【问题讨论】:

  • result 来自哪里?
  • 您的用户收藏有多大?
  • Users 集合仅包含 3 个用户。 result 是在 User.find() 之上声明的 var。 let result = new Array();
  • 是的,每当您在 forEach 中的最后一次计数完成时,它都会返回结果,这可能是也可能不是实际完成的最后一次计数。

标签: javascript node.js asynchronous mongoose


【解决方案1】:

你的直觉是正确的。在您的forEach 循环中,您对每个用户进行计数查询,当您按顺序发出请求时,它们不一定按顺序解决。这就是为什么检查index 是不值得信任的。这是一个应该成功的sn-p:

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')
        })
});

【讨论】:

  • 完美运行!谢谢 !我将不得不了解更多有关承诺的信息,但您的示例向我解释了很多。又是 Ty。
【解决方案2】:

您必须使用 Promise 才能获得确切的结果。

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. of node。

【讨论】:

  • 我的node版本是最新的。
  • 在这里使用async / await 肯定是个好主意。但是你似乎真的把这段代码复杂化了..特别是因为你使用的是async / await
猜你喜欢
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 2015-12-29
  • 1970-01-01
  • 2020-07-28
相关资源
最近更新 更多