Node.js 为nodejs中mongo查询外部的变量赋值

Node.js 为nodejs中mongo查询外部的变量赋值,node.js,mongoose,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.s

现在我有这个密码

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个变量,但我没有成功


就我所看到的,我不得不使用异步,但我在使用异步时遇到了一些问题。

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

这应该行得通

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


});
使用Async/Await是一个更简洁的解决方案

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

});

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

这应该行得通

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


});
使用Async/Await是一个更简洁的解决方案

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

});

萨西的另一个答案是正确的,但你可能会遇到错误。由于每个承诺上的
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解释的答案。

Sashi的另一个答案是正确的,但您可能会遇到错误。由于每个承诺上的
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解释的答案。

我不喜欢太多Lanlee先生的解决方案。这是一种典型的情况,在这种情况下,使用async/await确实是有意义的。无论如何,Hugo的解决方案(第二个,使用async await),即使它能正常工作,也会使四个查询按顺序进行,一个接一个地进行。如果您想要一个干净、有效且并行的解决方案,请选中以下选项:

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

我不太喜欢Lanlee先生的解决方案。这是一种典型的情况,在这种情况下,使用async/await确实是有意义的。无论如何,Hugo的解决方案(第二个,使用async await),即使它能正常工作,也会使四个查询按顺序进行,一个接一个地进行。如果您想要一个干净、有效且并行的解决方案,请选中以下选项:

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

如果我在显示[object Promise]而不是json之后执行console.log(userData)。@Hugo这是因为
console.log
通常不会等待Promise解析,它会在当前状态下记录它。如果需要,可以在此处使用
async wait
magic。但是这个解决方案可能会遇到问题,因为您可以多次返回res.status。如果我使用console.log(userData),那么在显示[object Promise]而不是json之后,
async await
方法和
try catch
会达成一致。@Hugo这是因为
console.log
通常不会等待承诺的解决,它以当前状态记录它。如果需要,可以在此处使用
async wait
magic。但是这个解决方案可能会遇到问题,因为您可以多次返回res.status同意
async await
方法和
try catch
您比我更擅长:)@Hugo如果您不太习惯使用async/await,请使用这个方法:)@Hugo如果您不太习惯使用这个方法,请使用这个方法异步/等待