我正在尝试创建一个网页,该网页的左侧有我正在处理的所有当前项目的实例,因此我需要一个.forEach()函数才能在其中循环浏览所有项目。为了显示它,但另一方面,我需要显示当前选择的信息。
请先看一下我的代码块,以便我可以尝试解释我想做的事情背后的思考过程。
因此,选择在该网页上显示的单个项目的信息没有任何问题。我使用.findOne()函数来挑选所需的信息。
我面临的问题是,我还需要传递一个连接到.find()函数的var,以传递数据库的所有元素。我这样做的方式是,我认为我可以通过手动运行.find()函数,然后将其返回,从而将Projects.find()分配给allProjects来设置allProjects的定义。
app.get('/projects/:url', (req, res) => {
Projects.findOne({ Url: req.params.url }, (err, foundProject) => {
if (err) {
console.log(err);
} else {
res.render('show', {
foundProject: foundProject,
allProjects: Projects.find({}, (err, allProjects) => {
if (err) {
res.send('error');
} else {
return allProjects;
}
})
});
}
});
});
我认为,通过返回allProjects并将其分配给allProjects,我可以在show.ejs页面中使用allProjects变量。
不幸的是,我收到一条错误消息“ allProjects.forEach()未定义”,这使我相信在我定义allProjects的app.js中,没有为其分配我要分配的正确值。
答案 0 :(得分:1)
您似乎期望return 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:
});
}
});
});
});
现在这仍然是令人眼花code乱的代码,即使这是相对简单的Node代码,此处的嵌套也已完全失控。
为了进行比较,下面是使用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({})
});
});
通过这种方式确实没有太多。 await
的工作基本上停滞在那条线上,并等待诺言得到解决或产生错误。照常使用try { ... } catch
捕获产生的任何错误。