ExpressJs ожидание до получения данных MongoDB и l oop до вывода - PullRequest
1 голос
/ 24 апреля 2020

У меня проблемы с тем, чтобы понять, как это работает, у меня есть одна таблица из MongoDB (коллекция) для комментариев и другая коллекция для пользователей.

Когда страница загружается, она ищет коллекцию комментариев и выбирает соответствующие комментарии, а затем выполняет поиск в таблице пользователей, чтобы найти имя пользователя, который сделал комментарий, данные будут объединены, а затем ответ отправлено.

Однако вывод отправляется до того, как данные извлекаются из пользовательской таблицы и добавляются. Как я могу это исправить, вот мой код

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

1 Ответ

1 голос
/ 24 апреля 2020

Вы не возвращаете promise из функции delayedProcess.

Там вы go: -

  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 возвращает обещание, вам не нужно использовать синтаксис 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 })
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...