将MongoDB响应推送到数组不起作用

时间:2019-05-09 00:38:10

标签: javascript mongodb mongoose

我正在尝试将所有mongoDB结果添加到数组并将其作为后响应发送。来自mongodb的每个响应的单个console.log都输出数据。但是,当我尝试将数据推入events数组时,它似乎无法正常工作。当我最后做console.log(events)时,它只会记录一个空数组。有什么想法吗?

calendar.post('/getEvents', (req, res) => {
  let events = []
  // Add all budget dates to events array
  Budget.find({
    userEmail: req.body.userEmail
  })
    .then(budgets => {
      // console.log(budgets)
      for (let i = 0; i < budgets.length; i++) {
        events.push(budgets[i])
      }
    })
  // Add all notes dates to events array
  Notes.find({
    userEmail: req.body.userEmail
  })
    .then(notes => {
      // console.log(notes)
      for (let i = 0; i < notes.length; i++) {
        events.push(notes[i])
      }
    })
  // Add all study plan dates to events array
  StudyPlan.find({
    userEmail: req.body.userEmail
  })
    .then(studyplans => {
      // console.log(studyplans)
      for (let i = 0; i < studyplans.length; i++) {
        events.push(studyplans[i])
      }
    })
  // Add all todo list dates to events array
  TodoList.find({
    userEmail: req.body.userEmail
  })
    .then(todolists => {
      // console.log(todolists)
      for (let i = 0; i < todolists.length; i++) {
        events.push(todolists[i])
      }
    })
  console.log(events)
  res.send(events)
})

编辑:

这是我向该路由发出发布请求后的控制台(我在控制台日志中添加了“预算:”和“事件:”,以便于阅读)

Events: []
Budgets: [ { duration: 7,
    _id: 5ccd88cb4c13380d84446673,
    title: 'bla',
    amount: null,
    startDate: 2019-05-04T12:42:45.000Z,
    userEmail: 'test@gmail.com',
    spending: [],
    __v: 0,
    expenses: [] },
  { duration: 7,
    _id: 5ccd89c04c13380d84446674,
    title: 'bla2',
    amount: null,
    startDate: 2019-05-04T12:46:52.000Z,
    userEmail: 'test@gmail.com',
    spending: [],
    __v: 0,
    expenses: [] } ]

2 个答案:

答案 0 :(得分:0)

Javascript的异步正在显示。您正在控制台记录日志并在任何查询实际完成之前发送响应。

这是我草拟的解决方案,可以解决您要完成的工作

calendar.post('/getEvents', async (req, res) => {
    const { userEmail } = res.body;

    try {
        const results = await Promise.all([
            Budget.find({userEmail}),
            Notes.find({userEmail}),
            StudyPlan.find({userEmail}),
            TodoList.find({userEmail}),
        ]);

        const events = [].concat.apply([], results);

        console.log(events);
        res.send(events);
    }
    catch (error) {
        return res.status(500).send(error);
    }
});

本质上,await Promise.all等待(暗示)为所有解决方案提供的承诺数组。这些查询全部并行运行,并返回到results变量中。

results此时是一个嵌套数组,如下所示:

results = [
[...], // Budget query results
[...], // Notes query results
[...], // StudyPlan query results
[...], // TodoList query results
]

[].concat.apply([], results)是“拉平”数组数组的简写。

此解决方案利用了async/await的优势。 async/await允许您以看起来同步的方式编写javascript。您可以在这里MDN async function

进行阅读。

答案 1 :(得分:0)

感谢 Cranky Coder ,他向我介绍了JavaScript的异步特性。这促使我进行了一些额外的研究,并将代码更改为以下代码,使我可以通过同步方式发送事件的响应:

const events = []

const getDates = async (userEmail) => {
  Budget.find({
    userEmail: userEmail
  })
    .then(budgets => {
      // console.log('Budgets:', budgets)
      for (let i = 0; i < budgets.length; i++) {
        console.log(budgets[i])
        events.push(budgets[i])
      }
    })
  // Add all notes dates to events array
  Notes.find({
    userEmail: userEmail
  })
    .then(notes => {
      // console.log(notes)
      for (let i = 0; i < notes.length; i++) {
        console.log(notes[i])
        events.push(notes[i])
      }
    })
  // Add all study plan dates to events array
  StudyPlan.find({
    userEmail: userEmail
  })
    .then(studyplans => {
      // console.log(studyplans)
      for (let i = 0; i < studyplans.length; i++) {
        console.log(studyplans[i])
        events.push(studyplans[i])
      }
    })
  // Add all todo list dates to events array
  TodoList.find({
    userEmail: userEmail
  })
    .then(todolists => {
      // console.log(todolists)
      for (let i = 0; i < todolists.length; i++) {
        console.log(todolists[i])
        events.push(todolists[i])
      }
    })

  return events
}

calendar.post('/getEvents', async (req, res) => {
  // Add all budget dates to events array
  getDates(req.body.userEmail).then(events => {
    res.send(events)
  })
})