使用全局变量在模块之间共享db

Luc*_*Luc 10 mongodb node.js

我正在使用'mongodb'模块处理nodejs/mongodb应用程序.该应用程序启动

node main.js
Run Code Online (Sandbox Code Playgroud)

在main.js中,我连接到db并将连接保存在'db'全局变量中.然后'db'用在'server'的内部方法中.我想避免将'db'作为全局变量,但没有找到正确的方法.

我目前的main.js:

var server      = require('./lib/server');
var MongoClient = require('mongodb').MongoClient;
var Server      = require('mongodb').Server;
var mongoClient = new MongoClient(new Server(HOST, PORT));
db = null;

// Database connection
mongoClient.open(function(err, mongoClient) {
  if(!err){
    // Database selection
    db = mongoClient.db(DB);

    // Launch web server
    server.start(); // usage of 'db' in this part 

  } else {
    console.log(err.message);
    process.exit(1);
  }
});
Run Code Online (Sandbox Code Playgroud)

想要更清洁的方法吗?

UPDATE

我终于在connection.js中创建了一个模块:

var config      = require('../config/config');
var url         = 'mongodb://' + config.db.host + ':' + config.db.port + '/' + config.db.name;
var MongoClient = require('mongodb').MongoClient;
var db          = null;

module.exports = function(cb){
  if(db){
    cb(db);
    return;
  }

  MongoClient.connect(url, function(err, conn) {
    if(err){
      console.log(err.message);
      throw new Error(err);
    } else {
      db = conn; 
      cb(db);
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

每次我需要连接时我都会打电话:

var connection = require('./connection');
connection(function(db){
  // doing some stuff with the db
});
Run Code Online (Sandbox Code Playgroud)

这非常有效.

这种方法有任何潜在的失败吗?

小智 6

我通常包含一个项目实用程序文件,其中包含许多这些内容,只是为了方便起见.它起到伪全局的作用,但没有全局性所带来的许多常见问题.

例如,

projectUtils.js

module.exports = {

  initialize: function(next){
    // initialization actions, there can be many of these
    this.initializeDB(next);
  },

  initializeDb: function(next){
    mongoClient.open(function(err, mongoClient) {
      if(err) return next(err);
      module.exports.db = mongoClient.db(DB);
      next();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

app.js

var projectUtils = require('projectUtils');

// (snip)
projectUtils.initialize(function(err) {
  if(err) throw err; // bad DB initialization
  // After this point and inside any of your routes,
  // projectUtils.db is available for use.
  app.listen(port);
}
Run Code Online (Sandbox Code Playgroud)

通过使用异步initialize()函数,您可以确保在启动服务器之前完成所有数据库连接,文件I/O等.


zs2*_*020 3

例如,您可以创建一个类似提供程序的包装器并将其放入provider.js 中。

Provider = function (db_name, host, port, username, password) {
    var that = this;
    var conn = generate_url(db_name, host, port, username, password); // you need to implement your version of generate_url()

    MongoClient.connect(conn, function (err, db) {
        if (err) {
            throw err;
        }
        that.db = db;
    });
};

//add the data access functions
Provider.prototype.getCollection = function (collectionName, callback) {
    this.db.collection(collectionName, collectionOptions, callback);
};

exports.Provider = Provider;
Run Code Online (Sandbox Code Playgroud)

这是您使用该提供程序的方式:

var db = new Provider(db_name, host, port, username, password);
db.getCollection('collection name', callback);
Run Code Online (Sandbox Code Playgroud)