在Node.js中的Mongo查询外部为变量分配值

时间:2019-01-23 14:51:55

标签: node.js mongoose

现在我有此代码

router.get('/export', function(req, res, next) {
var postData, eventData, messageData, userData

    Posts.list().then(data=> {

    var jsonOutput=JSON.stringify(data)
    postData=jsonOutput //this doesnt work
})
.catch(erro => res.status(500).send('error'))
Events.list().then(data=> {
    var jsonOutput=JSON.stringify(data)
    eventData=jsonOutput //this doesnt work
})
.catch(erro => res.status(500).send('error'))
Messages.list().then(data=> {
    var jsonOutput=JSON.stringify(data)
    messageData=jsonOutput //this doesnt work

})
.catch(erro => res.status(500).send('error'))
Users.list().then(data=> {
    var jsonOutput=JSON.stringify(data)
    userData=jsonOutput //this doesnt work
})
.catch(erro => res.status(500).send('error')) 


 //Then when all data from colections is retrieve i want to use the 4 variables that i created in the beggining
});

所以从根本上说,我试图从mongo数据库中检索数据,然后将结果分配给我创建的这4个变量,但没有成功。

对于我所看到的,我必须使用异步,但是我在执行时遇到了一些麻烦。

3 个答案:

答案 0 :(得分:1)

Sashi的另一个答案是正确的,但是您可能会遇到错误。由于您对每个promise的catch语句返回500,因此,如果在查询过程中发现多个错误,Express将不会发送错误或每次发送500个错误,而是会尝试发送一个错误。 见下文。

router.get('/export', function(req, res, next) {
  var postData, eventData, messageData, userData

  try {
    postData = Posts.list().then(data=> {
      return JSON.stringify(data);
    });
    eventData = Events.list().then(data=> {
      return JSON.stringify(data)
    });
    messageData = Messages.list().then(data=> {
      return JSON.stringify(data);
    })
    userData = Users.list().then(data=> {
      return JSON.stringify(data)
    });
  } catch (err) {
    // this should catch your errors on all 4 promises above
    return res.status(500).send('error')
  }

 // this part is optional, i wasn't sure if you were planning
 // on returning all the data back in an object

  const response = {
    postData,
    eventData,
    messageData,
    userData,
  };

  return res.status(200).send({ response })
});

有关为何您无法对变量进行突变的解释,请参见Sashi的解释。

答案 1 :(得分:1)

我不喜欢太多mrlanlee解决方案。这是典型的情况,使用异步/等待确实有意义。无论如何,Hugo的解决方案(第二种方案,它具有异步等待),即使它能正常工作,也将按顺序进行四个查询,一个接一个地进行。如果您想要一个干净,可行且并行的解决方案,请检查以下内容:

router.get('/export', async function(req, res, next) {
   let data
   try {
      data = await Promise.all([
         Posts.list(),
         Events.list(),
         Messages.list(),
         Users.list()
      ]);
   // at this point, data is an array. data[0] = Posts.list result, data[1] = Events.list result etc..
   res.status(200).json(data)
   } catch (e) {
    res.status(500).send('error');  
   }    
});

答案 2 :(得分:0)

在异步代码之外定义的变量超出了异步函数的范围。因此,您无法将异步函数的返回值存储在这些变量中。

这应该有效。

router.get('/export', function(req, res, next) {
var postData, eventData, messageData, userData

    postData = Posts.list().then(data=> {

        var jsonOutput=JSON.stringify(data);
        return jsonOutput;
    }).catch(erro => res.status(500).send('error'));

    eventData = Events.list().then(data=> {
        var jsonOutput=JSON.stringify(data);
        return jsonOutput;
    }).catch(erro => res.status(500).send('error'));

    messageData = Messages.list().then(data=> {
        var jsonOutput=JSON.stringify(data);
        return jsonOutput;

    }).catch(erro => res.status(500).send('error'));

    userData = Users.list().then(data=> {
        var jsonOutput=JSON.stringify(data);
        return jsonOutput;
    }).catch(erro => res.status(500).send('error'));


});

使用异步/等待是一个更整洁的解决方案。

router.get('/export', async function(req, res, next) {
var postData, eventData, messageData, userData;
try{
    postData = await Posts.list();
    eventData = await Events.list();
    messageData = await Messages.list()
    userData = await Users.list();
catch (e){
    res.status(500).send('error');  
}

});