Asynchronous issue within nodejs/mongodb code

时间秒杀一切 提交于 2019-12-25 06:44:41

问题


I am new to nodejs/express/mongodb/jade and I have been trying for some time now to put together a simple site to help facilitate a more efficient way of reaching back to past data and being able to reuse it quickly. I determined the easiest way to us it would be do have a dynamic URL and had started to make good progress and then ran into a road block.

End Goal: I am looking to use the URL params to determine which data is returned. Ran locally the syntax would look like localhost/:collection/:id. As an example it'd look like: localhost/lastyear/aug2001. Thus the resulting page would display the data in the collection lastyear where the _ID is equal to aug2001.

To achieve this I currently I have the route in index.js set as:

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;

The structure of a doc within the collection looks as something as follows:

{
     "_id": "aug2001"
     "header": "header text"
     "content": "content text"
     "item" : "items text"
}

For testing to see some form of data my jade file for dataentry looks as follows(I know tabbing is important in jade and it may not look correct here in the post but I made sure the tabs are correct):

block content 
     p Finding info...
     p= data.header
     p= data.content
     p= data.item

When navigating to /lastyear/aug2001 all I see is the page load "Finding info..." and I am not sure what I am missing as far as the jade syntax goes in order to display the doc data. I appreciate any help/suggestions of a more efficient way to achieve my end result.

EDIT: The real issue was not with JADE displaying but rather a asynchronous db call when pulling data out of the db.


回答1:


From what i see you have asynchronous problem here.

Try like this

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

Hope this helps.




回答2:


Code not checked


As @Mykola Borysyuk mentioned, this seems to be an asynchronous callback problem. In your code, collection.findOne({ id: req.params.id },{}) is an asynchronous function, so you have no idea when it will be executed. As you are rendering the page from outside the function callback, it would seem that entry is not modified before the rendering call occurs.

As mentioned in the above answer, one way to do this is by creating a callback function, and rendering the page from inside the callback. That would be as @Mykola showed. For sake of clarity, I'm giving it below.

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

This should work fine. That being said, there is another way to make the rendering operation wait till the asynchronous function finishes execution. That can be done using promises.

That can be done like:

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

I haven't checked my code, but hope this helps!



来源:https://stackoverflow.com/questions/39302920/asynchronous-issue-within-nodejs-mongodb-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!