在Node.js中,我是在“需要”时创建一个新对象吗?

时间:2011-04-26 18:45:20

标签: node.js require mongoose

所以,我不确定的是。如果在 ModuleA 中,我有:

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或什么都没有?

感谢。

2 个答案:

答案 0 :(得分:16)

我刚用最新的节点V0.4.6做了几次测试。我确认了以下内容:

  1. 从“require”返回的变量是单例。
  2. 后续更改将在包含它的所有其他模块中更改所需模块的数据。
  3. Mongoose的联系有点奇怪。即使断开连接并将其设置为新的连接路径,它仍然使用旧的连接路径。
  4. 所以,我的意思是上面的第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
    

    因此,它是一个单身人士。不仅仅是本地模块。

答案 1 :(得分:3)

我遇到过这篇文章,虽然接受的答案显示它是一个Singleton,但我对原始问题的回答“在Node.js中,我是否在”需要“时创建一个新对象?”是“它取决于”。

murvinlai的答案/逻辑仍然适用于最新版本的Node(撰写本文时为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中存储缓存的值),但最后是你创建一个新对象,取决于..