简体   繁体   English

Node.js 模块是单例吗?

[英]Is a Node.js module a singleton?

I used to implement singleton this way:我曾经以这种方式实现单例:

class MySomething {
    constructor(props) {}
}

let myInstance = null;
module.exports = (props) => {
    //first time call
    if(props) {
        myInstance = new MySomething (props);
    return myInstance;
} else {
return myInstance;
}

this assumes that at app.js (entry file) I will call first:这假设在 app.js (入口文件)我将首先调用:

require('./MySomething')(props)

then everywhere in the project I use:然后在我使用的项目中的任何地方:

const instanceOfSomething = require('./MySomething')();

I discovered that every time I got a new instance!我发现每次我得到一个新实例时!

What's wrong in my code?我的代码有什么问题?

I tried also this way:我也试过这样:

class MySomething {...}

const mySomething = (function() {
  
    let myInstance = null;

    return {
    
        init: function() {
            myInstance = new MySomething();
        }, 

        getInstance: function() {
            return myInstance ;
        }
    }   
 
})();

module.exports = mySomething;

and I got the some problem when importing this module from different files, anyone can explain to me?从不同文件导入这个模块时我遇到了一些问题,任何人都可以向我解释一下吗?

every require of file create new instance of mySomething文件的每个要求都会创建 mySomething 的新实例

UPDATE更新

I tried this example now:我现在尝试了这个例子:

class MySomething {...}

const mySomething =  {
        myInstance: null,
        init: function() {
            myInstance = new MySomething();
        }, 
        getInstance: function() {
            return myInstance ;
        }
    }   

};

module.exports = mySomething;

The same problem happened, maybe it is related to my project structure, I will explain it here:也出现了同样的问题,可能和我的项目结构有关,这里解释一下:

the code below belongs to module "facts"下面的代码属于模块“事实”

facts folder contains a folder named "dao" this folder contains MySomething.js (the singleton) in the facts/index.js I have: fact 文件夹包含一个名为“dao”的文件夹,此文件夹包含我拥有的 fact/index.js 中的 MySomething.js(单例):

  const Localstorage = require('./dao/MySomething');
    
    exports.init = (path) => {
       Localstorage.init(path)
     
    }
    exports.Localstorage = Localstorage;

Now in a folder named "core" which contains the "facts" folder I re-exported the Localstorage again in "index.js" like this:现在在一个名为“core”的文件夹中,其中包含“facts”文件夹,我再次在“index.js”中重新导出了 Localstorage,如下所示:

 const facstModule = require('./facts');
    
    exports.Localstorage = facstModule.Localstorage;

Then in "schedule" folder which contains "Runtime.js" within I write:然后在包含“Runtime.js”的“schedule”文件夹中我写:

const { Localstorage } = require('../core');


setTimeout(() => {
const localstorageIns = Localstorage.getInstance(); //this is always null!
}, 5000)

In app.js file (entry point) I did:在 app.js 文件(入口点)中,我做了:

const facts =  require('./src/facts');
facts.init(__dirname);

Normally instance will be created before the timeout execute the callaback, But I noticed that there two instance of Localstorage which is singleton通常会在超时执行回调之前创建实例,但我注意到有两个 Localstorage 实例是单例的

Every require of file create new instance of mySomething because every time you return new object with init method and getInstance method.文件的每个要求都会创建 mySomething 的新实例,因为每次您使用init方法和getInstance方法返回新对象时。

If you need singleton you need do like this:如果你需要单例,你需要这样做:

class MySomething {
    constructor() {
        if (!MySomething.instance) {
            MySomething.instance = this;
        }
    }

    getInstance: function() {
        return MySomething.instance;
    }
}

module.exports = MySomething;

the cleanest way to do a singleton is做单例最干净的方法是

class MyClass () { ... }

module.exports = new MyClass()

if you need a singleton that gets instantiated once, I would do:如果您需要一个实例化一次的单例,我会这样做:

class MyClass () { ... }

let myClass
const MyClassSingleton = (...args) => {
  if (myClass) {
    return myClass
  }
  myClass = new MyClass(...args)
  return myClass
}

module.exports = MyClassSingleton
class Singleton {
    constructor() {
        this.my_obj;
    }

    static makeObject() {
        if (!this.my_obj) {
            this.my_obj = new Singleton();
        }
        return this.my_obj;
    }
    add() {
        return 1
    }
}


// so to get the object we need to call the makeobject method

const obj = Singleton.makeObject()

console.log(obj.add());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM