简体   繁体   中英

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:

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

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:

  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:

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

Then in "schedule" folder which contains "Runtime.js" within I write:

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


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

In app.js file (entry point) I did:

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

Every require of file create new instance of mySomething because every time you return new object with init method and getInstance method.

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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