Има 3 ключови точки, които трябва да разберете тук и след това ще ги обясня подробно.
- module.exports е обект и обектите се предават чрез копиране на препратка в JavaScript.
- 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);
}
}
)
};
Предупреждение:въпреки че е извън обхвата на този отговор, бъдете много внимателни с горния код, за да сте сигурни, че затваряте/връщате връзките по подходящ начин, в противен случай ще изтече връзка.