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