簡體   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