我有一个包含多个下拉列表的表单,需要使用MongoDB数据库中的值填充,在我的路由文件代码中看起来像这样:
Make.find({},function(err,allMakes){
if(err){
console.log("error while trying to get all makes from the database");
}else{
makes = allMakes;
}
Color.find({},function(err,allColors){
if(err){
console.log("error while trying to get all colors from the database");
}else{
colors = allColors;
}
我发生了8次,我需要查询数据库然后将结果放在局部变量中,以便将它作为一个参数传递给渲染函数:
res.render("viewname",{makes:makes,colors:colors....etc});
问题是在我的视图文件中我没有为params定义。
asynch nodejs代码的任何解决方案?!
答案 0 :(得分:3)
MongoDB调用是异步的,这意味着在res.render之前没有设置品牌,颜色等的值(" viewname");被称为。您需要嵌套异步调用,使用Promise.all,或者理想地使用像async这样的库来并行运行数据库调用,然后只有在所有数据库回调设置了值之后才调用res.render应传递给视图。
例如,如果您正在嵌套通话:
Make.find({}, function(err,allMakes) {
if (err) {
console.log("error while trying to get all makes from the database");
} else {
makes = allMakes;
}
Color.find({}, function(err,allColors) {
if (err) {
console.log("error while trying to get all colors from the database");
} else {
colors = allColors;
}
res.render("viewname",{makes:makes,colors:colors....etc});
}
}
答案 1 :(得分:1)
感谢所有试图帮助回答这个问题的人。
我找到了解决方案,解决方案是使用名为async的nodejs模块
http://caolan.github.io/async/docs.html#.series
工作代码如下所示:
router.get("/new",function(req,res){
// get vehicles makes available in the DB
var makes;
var colors;
var categories;
var usages;
var registrationCenters;
var fuelTypes;
var insuranceCompanies;
var insuranceCoverages;
async.series([function(callback){
Make.find({},function(err,allMakes){
if(err) return callback(err);
makes = allMakes;
callback(null,allMakes);
})
},function(callback){
Color.find({},function(err,allColors){
if(err) return callback(err);
colors = allColors;
callback(null,allColors);
})
},function(callback){
Category.find({},function(err,allCates){
if(err) return callback(err);
categories = allCates;
callback(null,allCates);
})
},function(callback){
Usage.find({},function(err,allUsages){
if(err) return callback(err);
usages = allUsages;
callback(null,allUsages);
})
},function(callback){
RegistraionCenter.find({},function(err,allCenters){
if(err) return callback(err);
registrationCenters = allCenters;
console.log(allCenters);
callback(null,allCenters);
})
},function(callback){
FuelType.find({},function(err,allTypes){
if(err) return callback(err);
fuelTypes = allTypes;
callback(null,allTypes);
})
},
function(callback){
InsuranceCompanies.find({},function(err,allCompanies){
if(err) return callback(err);
insuranceCompanies = allCompanies;
callback(null,allCompanies);
})
},function(callback){
InsuranceCoverages.find({},function(err,allCoverages){
if(err) return callback(err);
insuranceCoverages = allCoverages;
callback(null,allCoverages);
})
}
],function(err){
res.render("vehicles/new",{makes:makes,colors:colors,categories:categories,usages:usages,
registrationCenters:registrationCenters,fueltypes:fuelTypes,InsuranceCompanies:insuranceCompanies,insuranceCoverages:insuranceCoverages}
);
});
});
答案 2 :(得分:1)
我遇到类似的问题,在查询完成之前执行了res.render(),因此使应用程序崩溃了。 您可以通过以下方式解决此问题:
router.get('/yourroute', async (req, res) => {
try {
const allMakes = await Make.find({});
const allColors = await Color.find({});
res.render('viewname', { allMakes, allColors });
} catch (err) {
console.log(err);
}
});
答案 3 :(得分:0)
我认为这两个函数属于同一个(父)函数。你不能调用这样的两种方法,并期望在你需要它们的同时获得结果。你可以叠加像:
这样的方法Make.find({},function(err,allMakes){
if(err){
console.log("error while trying to get all makes from the database");
}else{
makes = allMakes;
Color.find({},function(err,allColors){
if(err){
console.log("error while trying to get all colors from the database");
}else{
colors = allColors;
methodForRender(makes, colors);
}
}
methodForRender可以是一个回调函数,您可以在其中返回Makes和Colors,或者只返回一个函数。但我更喜欢回调,因为最好在模型文件中使用这些方法,并在路径文件中渲染视图