Er zijn hier 3 belangrijke punten om te begrijpen en dan zal ik ze in detail uitleggen.
- module.exports is een object en objecten worden doorgegeven via een kopie van de referentie in JavaScript.
- vereiste is een synchrone functie.
- client.connect is een asynchroon functie.
Zoals je suggereerde, is het een kwestie van timing. node.js kan niet weten dat module.exports later gaat veranderen. Dat is niet het probleem. Hoe zou het dat weten?
Wanneer require
wordt uitgevoerd, vindt het een bestand dat voldoet aan de vereisten op basis van het pad dat u hebt ingevoerd, leest het en voert het uit, en cachet module.exports zodat andere modules require
dezelfde module en hoeft deze niet opnieuw te initialiseren (wat de variabele scoping, enz. zou verpesten)
client.connect is een asynchrone functieaanroep, dus nadat u het hebt uitgevoerd, voltooit de module de uitvoering en de require
call slaat een kopie op van de module.exports-referentie en retourneert deze naar users.js. Dan stel je module.exports = db
. in , maar het is te laat. U vervangt de module.exports-referentie door een verwijzing naar db, maar de module-export in het knooppunt require
cache wijst naar het oude object.
Het is beter om module.exports te definiëren als een functie die een verbinding krijgt en deze dan als volgt doorgeeft aan een callback-functie:
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);
}
}
)
};
Waarschuwing:hoewel dit buiten het bestek van dit antwoord valt, moet u zeer voorzichtig zijn met de bovenstaande code om ervoor te zorgen dat u de verbindingen op de juiste manier sluit/retourneert, anders lekt u verbindingen.