Es gibt 3 wichtige Punkte, die hier verstanden werden müssen, und dann werde ich sie im Detail erklären.
- module.exports ist ein Objekt und Objekte werden per Referenzkopie in JavaScript übergeben.
- require ist ein synchronous Funktion.
- client.connect ist ein asynchroner Funktion.
Wie Sie schon sagten, ist es eine Sache des Timings. node.js kann nicht wissen, dass sich module.exports später ändern wird. Das ist nicht das Problem. Woher soll es das wissen?
Wenn require
ausgeführt wird, findet es eine Datei, die seine Anforderungen basierend auf dem von Ihnen eingegebenen Pfad erfüllt, liest sie und führt sie aus und speichert module.exports zwischen, sodass andere Module require
können das gleiche Modul und müssen es nicht neu initialisieren (was den Gültigkeitsbereich von Variablen durcheinander bringen würde usw.)
client.connect ist ein asynchroner Funktionsaufruf, das heißt, nachdem Sie ihn ausgeführt haben, beendet das Modul die Ausführung und den require
call speichert eine Kopie der module.exports-Referenz und gibt sie an users.js zurück. Dann setzen Sie module.exports = db
, aber es ist zu spät. Sie ersetzen die Referenz module.exports durch eine Referenz auf db, aber das Modul export im Knoten require
Cache zeigt auf das alte Objekt.
Es ist besser, module.exports als eine Funktion zu definieren, die eine Verbindung herstellt und sie dann wie folgt an eine Callback-Funktion weitergibt:
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);
}
}
)
};
Warnung:Obwohl dies außerhalb des Rahmens dieser Antwort liegt, seien Sie sehr vorsichtig mit dem obigen Code, um sicherzustellen, dass Sie die Verbindungen ordnungsgemäß schließen/zurückgeben, da sonst die Verbindungen undicht werden.