渲染视图之前的多个Mongoose查询

时间:2016-08-12 15:56:42

标签: node.js mongodb express

我有一个包含多个下拉列表的表单,需要使用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代码的任何解决方案?!

4 个答案:

答案 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,或者只返回一个函数。但我更喜欢回调,因为最好在模型文件中使用这些方法,并在路径文件中渲染视图