Javascript node.js:如何将多个变量传递到视图中?

Javascript node.js:如何将多个变量传递到视图中?,javascript,node.js,mongodb,express,Javascript,Node.js,Mongodb,Express,我试图创建一个网页,在左边有我正在处理的所有当前项目的实例,因此我需要一个.forEach()函数来循环遍历所有项目以显示它,但在另一边,我需要显示当前选定的信息 请先看一下我的代码块,这样我就可以试着解释我试图做的事情背后的思想过程 所以我在选择我需要在这个网页上显示的单个项目的信息时没有遇到任何问题。我使用.findOne()函数来挑选我需要的信息 我面临的问题是,我还需要传递一个连接到.find()函数的var,以便传递数据库的所有元素。我这样做的方式是,我认为可以通过手动运行.find(

我试图创建一个网页,在左边有我正在处理的所有当前项目的实例,因此我需要一个.forEach()函数来循环遍历所有项目以显示它,但在另一边,我需要显示当前选定的信息

请先看一下我的代码块,这样我就可以试着解释我试图做的事情背后的思想过程

所以我在选择我需要在这个网页上显示的单个项目的信息时没有遇到任何问题。我使用.findOne()函数来挑选我需要的信息

我面临的问题是,我还需要传递一个连接到.find()函数的var,以便传递数据库的所有元素。我这样做的方式是,我认为可以通过手动运行.find()函数,然后返回它,从而将Projects.find()分配给所有项目来设置所有项目的定义

app.get('/projects/:url',(req,res)=>{
Projects.findOne({Url:req.params.Url},(err,foundProject)=>{
如果(错误){
控制台日志(err);
}否则{
res.render('show'{
foundProject:foundProject,
allProjects:Projects.find({},(err,allProjects)=>{
如果(错误){
res.send('error');
}否则{
归还所有项目;
}
})
});
}
});
});
我认为,通过返回所有项目,然后将其分配给所有项目,我可以在show.ejs页面中使用allProjects变量


不幸的是,我收到一个错误“allProjects.forEach()未定义”,这使我相信在我定义allProjects的app.js中,没有为它指定我想要的正确值。

看起来你希望
返回allProjects
来做些什么,但实际上被忽略了。除非你有一个可以调用的回调函数,否则它将进入空白状态,永远不会被任何人看到。这几乎适用于所有回调函数。他们不在乎函数返回什么值,因为它从来都不相关,他们想要的是通过给这个函数的回调得到的未来值

换句话说,结果是这样的:

asyncFunctionTakingCallback(function(cb) {
  cb(null, value); // This is the important value!
  return value; // Nobody cares about this value. Don't even bother.
});
要解决此问题,您需要将
render
调用移动到最内部的回调函数中:

app.get('/projects/:url', (req, res) => {
  Projects.findOne({ Url: req.params.url }, (err, foundProject) => {
    if (err) {
        console.log(err);
        // Return here to avoid another level of indentation below
        return;
    }

    Projects.find({}, (err, allProjects) => {
      if (err) {
        res.send('error');
      } else {
        res.render('show', {
          foundProject: foundProject,
          allProjects:
        });
      }
    });
  });
});
现在这仍然是一个令人眼花缭乱的代码量,这里的嵌套已经完全失控,尽管这是相对简单的节点代码

为了进行比较,这里有一个使用
async
函数的版本:

app.get('/projects/:url', async (req, res) => {
  let foundProject = await Projects.findOne({ Url: req.params.url });

  res.render('show', {
    foundProject: foundProject,
    allProjects: await Projects.find({})
  });
});

这样真的没什么大不了的。
wait
所做的基本上是在那条线上暂停,等待承诺得到解决或产生错误。任何产生的错误都应该像往常一样用
try{…}catch
捕获。

注意:值得注意的是,如果你要做很多节点代码,你真的需要学习如何和新的工作。像这样的回调驱动的代码很快就会变得难以维护的复杂,而无需大量的训练。相比之下,Promise代码更容易理解,而意外遗漏错误则更难。@tadman,我对promises和.then函数有点模糊的认识。也许我对这些概念缺乏理解,因为我不确定它们与我的问题有什么关系?根据我的理解,当一个任务比另一个任务需要更长时间才能完成时,您会使用承诺,这就是为什么您会使用.then()函数,因此程序知道在完成第一个任务后,它应该运行第二个任务。据我所知,从数据库中提取信息并不需要承诺。如果我错了,你能给我解释一下吗?你可以使用
然后
对异步事件进行排序,但是你也可以出于同样的目的使用回调。问题在于回调往往是嵌套的,以影响排序,而承诺可以与
然后
线性链接。记住,在Node中,几乎所有非平凡的东西都是异步函数,因此您将要执行大量异步代码。从数据库中提取信息绝对需要承诺。从运行在纳秒级的CPU的角度来看,从数据库中获取数据就像向火星发射火箭。到那里要花很长时间,所以在附近等是不现实的。任何超过几分之一毫秒的时间都将是异步的,对于复杂的查询,数据库调用可能需要几分钟以上的时间。@tadman我不知道。非常感谢你为我解释得如此清楚!