2017-07-07 47 views
0

我正在用Node.js,Express和Mongoose/MongoDB構建一個Web應用程序。創建Mongoose組織/類結構?

我遇到的一個問題是如何正確組織和構建與貓鼬有關的方法。我需要在我的路由中調用Mongoose功能,但所有示例均顯示使用Mongoose調用,而不用用原型構建單獨的文件或類。

IE。設置在線路

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

架構,並呼籲貓鼬,我想放貓鼬CRUD功能相關的邏輯和功能的輔助文件內,並呼籲他們在我的路線。當我用貓鼬單獨的類方法,不返回值(或者由於異步本性,我無法使用的結果),我創建一個服務對象

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

片段從我的貓鼬類:

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

回答

0

所以,有經驗,你就錯過了幾個關鍵的規則,之前,我們甚至進入「最佳」的方式來組織你的代碼。

  1. 當你處理異步方法時,你必須始終將它們(和它們的調用代碼)作爲異步處理,即 。在你的例子中,你的 getAllServiceDetails()函數既不返回承諾也不執行回調,所以你失去了上下文。
  2. 在同一個邏輯堆棧中同時使用承諾和回調會給你的大腦增加 認知負擔;儘量堅持一種風格或其他方式。

至於組織的最佳方式,我強烈的看在這種情況下拉出一個整體服務類,而是看編寫插件貓鼬,或者簡單地擴展貓鼬模式本身。如果您要爲多個模型編寫相同的代碼,插件會更加有用,因此我假設您不屬於這種情況,並繼續僅使用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); 
    }, 

另外請注意,我沒有添加錯誤處理;與異步/等待你只是使用try ... catch。

+0

嗨保羅,這是很棒的信息。我附加了模型的模式文件。對於特定的「getter」和「setter」查詢,你會在Mongoose模式中編寫所有的函數而不是單獨的文件嗎? – Jacob

+0

是的,絕對會這樣做。我只爲跨越多個模型的邏輯創建服務類。 – Paul