简体   繁体   中英

nodejs modules code execution

need a little assistance with an understanding nodejs code organization, so I'm from C++ world and suppose that didn't understand a principles.

So I need to implement some js module which should connect to MongoDB and exports a few methods for other modules: eg insert, update, delete.

when I write something like:

var db = MongoClient.connect(config.connectionString, {native_parser:true},function (err, db) {...});

exports.insert = function(a, b) {
    // db using
    //...
};

I suppose that "db" local static variable and will be initialized in any case. at the time of call "require('this module') " but seems it's not so, and db is uninitialized at the time of the call of exported functions? another question - I suppose this should be implemented using "futures" (class from c++, didn't find an analogue from js) to guaratee that db object is copmpletely constructed at the moment of the using??

I had worked with C++, Java before (sometime back, not now) and now working in nodejs. I think I understood your question. Here are some key points.

  1. Yes, Nodejs modules are somewhat like classes that they encapsulate the variables and you access only through public methods (exposed through exports). I think you are aware that there is no class implementation at all here, but it loosely maps to the behaviour.

  2. The key difference in nodejs is the asynchronous nature of resource instantiation. By this, I mean if there are 2 statements stmt1 and stmt2, if stmt1 is called and takes time, nodejs does not wait for it to end (that is synchronous behaviour), instead it moves on to stmt2. In pre-nodejs world, we assume that reaching stmt2 means stmt1 is complete.

  3. So, what is the workaround? How to ensure you do something after db connection is obtained. If your code is not making db calls immediately, you could assume that connection will be through. Or if you immediately want to invoke db, you write the code on a callback. Mongo exposes events called 'open' and 'error'. You can use this to ensure connection is open. Also it is best practise to track error event.

    db.on('error', console.error.bind(console, 'connection error'));

    db.once('open', function callback() { console.log("Connection with database succeeded."); // put your code });

I am not aware of C++ future and so cannot comment on that.

Hope this helps !

[Updated] To add example

You could have db.js for setting up db connection and expose Mongoose object to create models.

'use strict';

var Mongoose = require('mongoose'),
        Config = require('./config');

Mongoose.connect(Config.database.url);

var db = Mongoose.connection;

db.on('error', console.error.bind(console, 'connection error'));

db.once('open', function callback() {
    console.log("Connection with database succeeded.");
});

exports.Mongoose = Mongoose;
exports.db = db;

You can include db.js in the server.js like

var DB = require('db.js');

which will do the initialisation.

You then use mongoose (mongoose is a Object relational mapper to work with mongo and highly recommended) to get models of database objects as shown below.

//userModel.js

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,

var UserSchema = new Schema({
    uid : {type : Number,  required: false}
    , email : {type : String, get: toLower, set: toLower,  required: true, index: { unique: true } }
    , passwd : {type : String,  required: false}
); 

var user = mongoose.model('user', UserSchema);

module.exports = {
  User : user
};

For more information on mongoose, you can refer http://mongoosejs.com

The db is generally not closed as I use in web environment and is always on. There is db connection pooling maintained and connections are reused optimally. I saw noticed a thread in SO which adds more details. Why is it recommended not to close a MongoDB connection anywhere in Node.js code?

So the problem I see is that you want to use DB but since DB is returned async, it may or may not be available in the exported function, hence you need to convert the connect from async to sync.

Since MongoDB driver cannot do sync, i suggest you use a wrapper, i suggest mongoskin.

https://github.com/kissjs/node-mongoskin

var mongo = require('mongoskin');
var db = mongo.db(config.connectionString, {native_parser:true});

Now this should work for you.

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