繁体   English   中英

Node.js / MongoDB代码内的异步问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM