[英]Asynchronous issue within nodejs/mongodb code
我是nodejs / express / mongodb / jade的新手,并且我一直在尝试一段时间以建立一个简单的站点,以帮助促进更有效的方式来恢复过去的数据并能够快速重用它。 我确定最简单的方法是使用动态URL,并开始取得良好进展,然后遇到障碍。
最终目标:我正在寻找使用URL参数来确定返回哪些数据。 在本地运行语法类似于localhost /:collection /:id。 例如,它看起来像:localhost / lastyear / aug2001。 因此,结果页面将显示去年集合中的数据,其中_ID等于aug2001。
为此,我目前将index.js中的路由设置为:
var express = require('express');
var router = express.Router();
router.get('/:collection/:id', function(req, res) {
var db = req.db;
var collection = db.get(req.params.collection);
var entry = collection.findOne({ id: req.params.id },{})
res.render('dataentry',{ title: 'Information for: ' + req.params.collection + ' ' + req.params.id +'.', data: entry
});
});
module.exports = router;
集合中的文档结构如下所示:
{
"_id": "aug2001"
"header": "header text"
"content": "content text"
"item" : "items text"
}
为了测试以查看某种形式的数据,我的jade文件用于dataentry的外观如下(我知道制表符在jade中很重要,在本文中看起来可能不正确,但我确保制表符正确):
block content
p Finding info...
p= data.header
p= data.content
p= data.item
导航到/ lastyear / aug2001时,我看到的只是页面加载“ Finding info ...”,而且我不确定为了显示doc数据而在jade语法方面缺少什么。 我非常感谢您提供帮助/建议,以更有效的方式来达到最终结果。
编辑:真正的问题不是JADE显示,而是从数据库中提取数据时的异步数据库调用。
从我看来,您在这里有异步问题。
这样尝试
router.get('/:collection/:id', function(req, res) {
var db = req.db;
var collection = db.get(req.params.collection);
//this is async operation so you need to wait until it finish.
//and only then send response to page.
collection.findOne({ id: req.params.id },{}, function(err, entry){
res.render('dataentry',{ title: 'Information for: ' + req.params.collection + ' ' + req.params.id +'.', data: entry
});
});
});
希望这可以帮助。
代码未检查
如@Mykola Borysyuk所述,这似乎是一个异步回调问题。 在您的代码中, collection.findOne({ id: req.params.id },{})
是一个异步函数,因此您不知道何时执行。 从函数回调外部渲染页面时,似乎在渲染调用发生之前未修改该条目。
如上述答案中所述,一种方法是创建一个回调函数,并从回调内部渲染页面。 就像@Mykola所示。 为了清楚起见,我在下面给出。
var collection = db.collection(req.params.collection);
collection.findOne({ id: req.params.id },{}, function(error, data){
if(error){
console.log("Error: " + error);
}
else {
res.render('dataentry',{ title: 'Information for: ' + req.params.collection + ' ' + req.params.id +'.', data: data});
}
});
这应该工作正常。 话虽这么说,还有另一种方法可以使渲染操作等待异步函数完成执行。 可以使用诺言来完成。
可以这样完成:
var collection = db.collection(req.params.collection);
res.promise(collection.findOne({ id: req.params.id },{},function(error,data)).then(function(){
res.render('dataentry',{ title: 'Information for: ' + req.params.collection + ' ' + req.params.id +'.', data: data});
});
我尚未检查我的代码,但希望对您有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.