【问题标题】:ExpressJs wait till MongoDB fetch data and loop through before the outputExpressJs 等到 MongoDB 获取数据并在输出之前循环
【发布时间】:2020-08-07 16:36:03
【问题描述】:

我在想办法解决这个问题时遇到了麻烦,我有一个来自 MongoDB(集合)的表用于 cmets,另一个集合用于用户。

当页面加载时,它会查找评论集合并选择相关的cmets,然后搜索用户表以找到发表评论的用户的名称,然后将数据组合起来发送响应。

但是,在从用户表中提取数据并添加数据之前,会发送输出。我该如何解决这个问题,这是我的代码

  var output = []
  const Comments = require('comments.js')
  const Users = require('users.js')

  function delay( ) {
    return new Promise(resolve => setTimeout(resolve, 300))
  }

  async function delayedProcess(item) {
    await delay()
    Users.findById(item.user, async function(err, result) {
      Object.assign(item, {name: result.name})
      output.push(item)
    })
  }

  async function processArray(array) {
    const promises = array.map(delayedProcess)
    await Promise.all(promises)
    return res.json({data: output})
  }


  Comments.find({page_id: id}).sort({post_date:-1}).limit(6).then(function(data) {
    processArray(data)
  })

【问题讨论】:

    标签: javascript node.js mongodb express promise


    【解决方案1】:

    您没有从delayedProcess 函数返回promise

    你去吧:-

      const Comments = require('comments.js')
      const Users = require('users.js')
    
      const output = []
      function delayedProcess(item) {
        return new Promise((resolve, reject) => {
          Users.findById(item.user, function(err, result) {
            if (err) return reject (err);
            output.push({ ...item, name: result.name })
            return resolve()
          })
        })
      }
    
      async function processArray(array) {
        const promises = array.map(async(item) => {
          await delayedProcess(item)
        })
        await Promise.all(promises)
        return res.json({ data: output })
      }
    
      const data = await Comments.find({ page_id: id }).sort({ post_date: -1 }).limit(6)
      processArray(data)
    

    但是,您总是会得到串联的数组。所以取而代之的是全局,把它当作局部变量

      function delayedProcess(item) {
        return new Promise((resolve, reject) => {
          Users.findById(item.user, function(err, result) {
            if (err) return reject (err);
            return resolve({ ...item, name: result.name })
          })
        })
      }
    
      async function processArray(array) {
        const output = []
        const promises = array.map(async(item) => {
          const it = await delayedProcess(item)
          output.push(it)
        })
        await Promise.all(promises)
        return res.json({ data: output })
      }
    
      const data = await Comments.find({ page_id: id }).sort({ post_date: -1 }).limit(6)
      processArray(data)
    

    更简化:- 由于 mongodb 查询本身返回 promise,因此您不需要使用 new Promise 语法。

      async function processArray() {
        const array = await Comments.find({ page_id: id }).sort({ post_date: -1 }).limit(6)
        const output = []
        const promises = array.map(async(item) => {
          const it = await Users.findById(item.user).lean()
          item.name = it.name
          output.push(item)
        })
        await Promise.all(promises)
        return res.json({ data: output })
      }
    

    【讨论】:

    • 什么是精益功能,我找不到参考
    • Mongoose 返回 mongoose 对象,lean() 用于将其转换为普通对象。
    • 感谢您的回复,您救了我的命,我觉得 promises 有点难以理解,我相信我并不孤单
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多