Zde jsou 3 klíčové body, kterým je třeba porozumět a poté je podrobně vysvětlím.
- module.exports je objekt a objekty jsou předávány pomocí kopie reference v JavaScriptu.
- require je synchronní funkce.
- client.connect je asynchronní funkce.
Jak jste naznačil, jde o načasování. node.js nemůže vědět, že module.exports se později změní. To není problém. Jak to může vědět?
Když require
spustí, najde soubor, který splňuje jeho požadavky na základě zadané cesty, přečte jej a spustí a uloží do mezipaměti module.exports, aby ostatní moduly mohly require
stejný modul a nemusíte jej znovu inicializovat (což by narušilo rozsah proměnných atd.)
client.connect je asynchronní volání funkce, takže po jeho spuštění modul dokončí provádění a require
call uloží kopii reference module.exports a vrátí ji do users.js. Poté nastavíte module.exports = db
, ale už je pozdě. Nahrazujete odkaz module.exports odkazem na db, ale export modulu v uzlu require
cache ukazuje na starý objekt.
Je lepší definovat module.exports jako funkci, která získá spojení a poté jej předat funkci zpětného volání:
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);
}
}
)
};
Varování:i když to nespadá do rozsahu této odpovědi, buďte velmi opatrní s výše uvedeným kódem, abyste se ujistili, že jste správně uzavřeli/navrátili připojení, jinak dojde k úniku spojení.