ここで理解すべき3つの重要なポイントがあり、それからそれらを詳細に説明します。
- module.exportsはオブジェクトであり、オブジェクトはJavaScriptのcopy-of-referenceによって渡されます。
- requireは同期です 機能。
- client.connectは非同期です 機能。
あなたが提案したように、それはタイミングの問題です。 node.jsは、module.exportsが後で変更されることを認識できません。それは問題ではありません。どうやってそれを知るのでしょうか?
require
の場合 実行すると、入力したパスに基づいて要件を満たすファイルが検索され、それを読み取って実行し、module.exportsをキャッシュして、他のモジュールがrequire
できるようにします。 同じモジュールであり、再初期化する必要はありません(変数のスコープなどを台無しにする)
client.connectは非同期関数呼び出しであるため、実行後、モジュールは実行を終了し、require
callは、module.exports参照のコピーを保存し、users.jsに返します。次に、module.exports = db
を設定します 、しかしそれは手遅れです。 module.exports参照をdbへの参照に置き換えていますが、ノードrequire
でのモジュールエクスポート キャッシュは古いオブジェクトを指しています。
module.exportsを、接続を取得して、次のようなコールバック関数に渡す関数として定義することをお勧めします。
var mongodb = require("mongodb");
var client = mongodb.MongoClient;
module.exports = function (callback) {
client.connect('mongodb://host:port/dbname', { auto_reconnect: true },
function(err, db) {
if (err) {
console.log(err);
callback(err);
} else {
// export db as member of exports
callback(err, db);
}
}
)
};
警告:この回答の範囲外ですが、上記のコードに十分注意して、接続を適切に閉じる/返すようにしてください。そうしないと、接続がリークする可能性があります。