2013-08-01 26 views
10

私はnodejs/mongodbアプリケーションで 'mongodb'モジュールを使って作業しています。アプリケーションはグローバル変数を使用してモジュール間でdbを共有する

node 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); 
    } 
}); 

きれいな方法の任意のアイデア?

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

私は呼んで接続を取得する必要があるたびに:

var connection = require('./connection'); 
connection(function(db){ 
    // doing some stuff with the db 
}); 

これは非常に取り組んでいますよく

この方法で問題が発生する可能性はありますか?

+1

コンストラクタ(コンストラクタ依存関係インジェクション)でそれを使用しているモジュールに渡すか、そのインスタンスを含むモジュールを持っていて、他のモジュールがそれを必要とするモジュールを持っていて、dbインスタンスと必要なその他のサービス悪い) –

+0

本当にグローバルに留まるつもりならば、代わりに 'global.db'を使うよう指示します。少なくとも、無効なJSではありません。 – gustavohenke

+0

私はこのグローバルを取り除きたいと思っています:) – Luc

答えて

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; 

これは、プロバイダを使用する方法である:

var db = new Provider(db_name, host, port, username, password); 
db.getCollection('collection name', callback); 
+1

db.getCollectionを呼び出す前に接続が完了していることを確認できますか(コールバックメソッドが呼び出されていますか? – Luc

6

私は通常、ちょうどそれが簡単にするために、これらのものの数を含むプロジェクトユーティリティのファイルが含まれています。それは疑似グローバルとして機能しますが、通常の問題の多くが伴わずにグローバルが伴います。例えば

、非同期のinitialize()関数を使用することにより

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

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

を、あなたはすべてのことを確認することができますデータベース接続、ファイルI/Oなどは、サーバーの起動前に実行されます。

関連する問題