2011-04-26 76 views
24

所以,我不確定是什麼。如果ModuleA,我有:在Node.js中,我是否在「Require」時創建一個新對象?

var mongoose = require('mongoose'); 
mongoose.connect(pathA); 

而且在ModuleB,我有:

var mongoose = require('mongoose'); 
mongoose.connect(pathB); 

而且在主程序中,我有:

var mA = require('./moduleA.js'), 
mB = require('./moduleB.js'); 

所以,當我運行主程序時,我想我會創建兩個貓鼬「實例」,一個連接到pathA,一個連接到pathB,是嗎?

另外,在模塊B中,在我連接到pathB之前,它是否連接到pathA或者什麼也沒有?

謝謝。

回答

16

我剛剛用最新的節點V0.4.6做了一些測試。我確認了以下內容:

  1. 從「require」返回的變量是一個單例。
  2. 後續更改將在包含該模塊的所有其他模塊中更改所需模塊的數據。
  3. 貓鼬的連接有點奇怪。即使斷開連接並將其設置爲新的連接路徑,它仍會使用舊的連接路徑。

所以,我的意思是由上述各點1和2:

如果你有模塊主

var myStr = 'ABC'; 
module.exports.appendStr = function(data) { 
    myStr += ' ' + data;  
}; 
module.exports.output = function() { 
    console.log("Output: " + myStr); 
}; 

如果您有其他兩個模塊:

模塊A

var mc = require('./moduleMaster.js'); 
var ma = function() {mc.appendStr(' MA '); }; 
ma.prototype.output = function() { 
    mc.output(); 
} 
module.exports.create = function() { 
    return new ma(); 
}; 

module.exports._class = ma; 

模塊B

var mc = require('./moduleMaster.js'); 
var mb = function() {mc.appendStr(' MB '); }; 
ma.prototype.output = function() { 
    mc.output(); 
} 
module.exports.create = function() { 
    return new mb(); 
}; 

module.exports._class = mb; 

現在,當你運行一個測試腳本,需要模塊A和模塊B,實例化它們輸出:

mTestA.output(); 
mTestB.output(); 

您將得到以下的輸出:

ABC MA 
ABC MA MB 

而不是

ABC MA 
ABC MB 

因此,它是一個單身人士。不只是本地的模塊。

3

我遇到了這篇文章,雖然接受的答案顯示它是一個單例,但我對原始問題的迴應「在Node.js中,我是否在創建新對象時需要」「?是「視情況而定」。

murvinlai的答案/邏輯仍然保持通過節點(v0.10.18截至發稿時)的最新版本屬實,但這是如果你有你需要的文件設置的方式。例如,我試圖用一個更詳細的例子,以避免任何混亂,如果你有在user.js的下面的「用戶」代碼(結構比murvinlai的回答是不同的)

/** 
* User Model 
*/ 
function modelUser() { 
    var User = { 
     /** 
     * User::_id 
     * 
     * @var integer 
     */ 
     "_id" : null, 

     /** 
     * Set id 
     * 
     * @param integer id 
     * @return User 
     */ 
     "setId" : function(id) 
     { 
      User._id = id; 
      return User; 
     }, 

     /** 
     * Get id 
     * 
     * @return integer 
     */ 
     "getId" : function() 
     { 
      return User._id; 
     }, 

    } 

    return User; 

} 
exports.modelUser = modelUser; 

現在,如果你拿了上面的代碼,你可能會發現,在許多情況下沒有修改,你不會有Singleton問題。 IE與:

var user1 = require("./application/models/User.js").modelUser(); // In one module 
var user2 = require("./application/models/User.js").modelUser(); // In another module 

user1.setId(1); 

console.log(user1.getId()); 
console.log(user2.getId()); 

您將得到1,null。另外,我甚至不確定你會需要這個,但是你可以在require上使用new操作符(因爲它本質上只是返回一個函數)。 IE與:

var user1 = new require("./application/models/User.js").modelUser(); // In one module 
var user2 = new require("./application/models/User.js").modelUser(); // In another module 

user1.setId(1); 

console.log(user1.getId()); 
console.log(user2.getId()); 

而且你會得到相同的輸出。

同樣,原來的問題有點寬泛(這個問題可能最終與貓鼬有關(如Murvinlai的回答中的第3部分所述),但以上是另一種做事方式的例子一個實際的新對象關閉了require()的每一個,現在你可能想在做這件事之前考慮一下,因爲有時候你會想要Singleton(比如將緩存值存儲在ORM/Mapper中),但是在關閉時是在創建新的對象,這取決於..

+0

好一點值得一提的是,這種方法對於在Javascript中創建對象比使用「原型」的做法更慢V8不可能的相同的兩個不同的實例之間的區別「課堂「。更多細節,請看:http://thenodeway.io/posts/designing-custom-types – 2015-03-27 18:00:00

相關問題