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

Node.js 渲染视图之前的多个Mongoose查询,node.js,mongodb,express,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({

我有一个包含多个下拉列表的表单,需要使用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;
}
res.render("viewname",{makes:makes,colors:colors....etc}); 
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}
       );
   });


});
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);
  }
});
我有8次需要查询数据库,然后将结果放入局部变量中,以便将其作为参数传递给呈现函数,如下所示:

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


});
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);
  }
});
问题是,在我的视图文件中,参数没有定义


异步节点代码有什么解决方案吗

我假设这两个函数在同一个父函数中。您不能调用两个这样的方法,并期望在需要它们的同时得到结果。您可以使用以下方法进行叠瓦:

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可以是一个回调函数,您可以在其中返回品牌和颜色,也可以只是一个函数。但是我更喜欢回调,因为在模型文件中有这样的方法更好,在路由文件中呈现视图更好。我假设这两个函数在同一个父函数中。您不能调用两个这样的方法,并期望在需要它们的同时得到结果。您可以使用以下方法进行叠瓦:

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可以是一个回调函数,您可以在其中返回品牌和颜色,也可以只是一个函数。但我更喜欢回调,因为最好在模型文件中有这样的方法,并在路由文件中呈现一个视图

MongoDB调用是异步的,这意味着在res.renderviewname之前不设置make、colors等的值;正在呼叫。您需要嵌套异步调用,使用Promise.all,或者理想情况下使用类似于并行运行DB调用的库,然后仅在所有DB回调设置了应传递给视图的值之后才调用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}); 
    }
}

MongoDB调用是异步的,这意味着在res.renderviewname之前不会设置make、colors等的值;正在呼叫。您需要嵌套异步调用,使用Promise.all,或者理想情况下使用类似于并行运行DB调用的库,然后仅在所有DB回调设置了应传递给视图的值之后才调用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}); 
    }
}

感谢所有试图帮助回答这个问题的人

我已经找到了解决方案,解决方案是使用名为async的nodejs模块

工作代码如下所示:

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


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

感谢所有试图帮助回答这个问题的人

我已经找到了解决方案,解决方案是使用名为async的nodejs模块

工作代码如下所示:

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


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

我遇到了一个类似的问题,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}); 
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}
       );
   });


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

我遇到了一个类似的问题,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}); 
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}
       );
   });


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

你能告诉我实际的问题是什么吗?你在找什么?@GandalftheWhite问题是要作为参数发送到渲染方法的值没有被指定预期值,render方法在方法调用以启动参数之前被执行。你能告诉我实际的问题是什么吗?你在寻找什么?@GandalftheWhite问题是作为参数发送到render方法的值没有被指定预期的值,换句话说,render方法在方法调用以启动参数之前执行。可能会添加一些错误处理,因为如果err为true,则不会定义make和colors。如果err为true,则可能会添加一些错误处理,因为不会定义make和colors。