创建Mongoose组织/类结构?

时间:2017-07-07 03:19:48

标签: javascript node.js express mongoose

我正在使用Node.js,Express和Mongoose / MongoDB构建一个Web应用程序。

我遇到的一个问题是如何正确组织和构建与Mongoose相关的方法。我需要在我的路由中调用Mongoose功能,但是所有示例都显示使用Mongoose调用而不构造单独的文件或带有原型的类。

IE。设置架构并在路由中调用mongoose

SiteModel.find({}, function(err, docs) {
if (!err){ 
    console.log(docs);
    process.exit();
} else {throw err;}
});

我想将mongoose CRUD函数放在与逻辑和功能相关的帮助文件中,并在我的路由中调用它们。当我使用单独的类方法与mongoose时,没有返回任何值(或者由于异步性质,我无法使用结果)

//Router file
var myService =  require('../helpers/ServiceStatus');

router.get('/', authService.isLoggedIn, function(req,res){

   var serviceObject = new myService(); //Initialize class with Mongoose functions

   async.parallel({
       modelAFind: function(cb){
           //Mongoose class method is called
           var response= serviceObject.getAllServiceDetails(); 
           cb(null, response);
       },
       modelBFind: function(cb){
           cb(null, 2); //filler
       }
   }, function(results){
       console.log("Results of query: " + results);
   });

我的Mongoose类中创建服务对象的片段:

//ServiceStatus.js
//Constructor
function ServiceStatus() {

}

ServiceStatus.prototype.getAllServiceDetails = function(){

    var query = SiteModel.find({});
    var promise = query.exec();

    promise.then(function (doc) {
        return doc;
    });
};

处理异步的最佳方法是什么,用Mongoose逻辑构造单独的帮助文件并在路由中调用它们:promises,带回调的函数等?感谢。

*编辑 - 添加了架构文件

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// set up a mongoose model
module.exports = mongoose.model('SiteModel', new Schema({

    id: String,
    service: {type: String, unique: true, required: true},
    status: String,
    settings: Object,
    lastCheck: String

}

,{
    timestamps: true
}));

1 个答案:

答案 0 :(得分:0)

所以,在我们进入"最好的"之前,你有一些关键的经验法则。组织代码的方法。

  1. 当您处理异步方法时,您必须始终对待 他们(和他们的调用代码)async。在你的例子中,你的 getAllServiceDetails()函数既不返回promise也不返回 执行回调,因此您丢失了该上下文。
  2. 在同一个逻辑堆栈中同时使用Promises和Callback 对大脑的认知负担;试着坚持一种风格或者 另一方面。
  3. 至于组织的最佳方式,我强调在这种情况下拉出一个完整的Service类,而是考虑编写一个mongoose插件,或者只是扩展mongoose架构本身。如果您要为多个模型编写相同的代码,插件会更有用,因此我假设您不是在这种情况下继续使用仅适用于SiteSchema的示例。您不会在此处显示您的架构代码,因此我不确定您在路由代码中调用SiteModel.find(...)是否真正节省了什么,但为了论证,您可以这样做:

    SiteSchema.statics.list = function(cb) {
      SiteSchema.find({}, cb);
    }
    

    这使您无需传入调用代码中的空对象,但调用代码仍然必须如下所示:

    /** snip **/
    modelAFind: function(cb){
           //Mongoose class method is called
           var response= serviceObject.list(cb); 
       },
    

    如果您正在使用最新版本的节点,您还可以访问async / await语法,这可能更符合您的喜好。请注意我的示例未经过测试,但它看起来应该是这样的:

    SiteSchema.statics.list = async function() { // note the 'async' keyword 
      // latest versions of Mongoose, this returns a Promoise
      return SiteSchema.find({});
    }
    

    然后您的消费代码可以

    /** snip **/
    modelAFind: function(cb){
           //Mongoose class method is called
           var response= await serviceObject.list(); // note 'await' keyword
           cb(null, response);
       },
    

    另请注意,我没有添加错误处理;使用async /等待你只需使用try ... catch。