I'd like to initialize module in asynchronous way and come up with couple of ideas. I need DB object with list of collections from Mongo and other data, but list of files in ./
will do for brevity.
I can't export function or class because I need require('db')
to return same object everytime.
First and simplest what came to my mind is to assign module.exports
to Object
and populate it later:
var exports = {};
module.exports = exports;
require('fs').readdir('.', function(err, files) {
exports.error = err;
exports.files = files;
});
Bad thing — I don't really know from outside when list is ready and no good way to check for errors.
Second way I've comed up with is to inherit EventEmitter
and notify everyone that DB is ready or error occured. If everything ok - keep going.
var events = require('events');
var util = require('util');
function Db() {
events.EventEmitter.call(this);
this.ready = false;
this.files = null;
this.initialize();
}
util.inherits(Db, events.EventEmitter);
Db.prototype.initialize = function() {
if (this.ready)
return this.emit('ready');
var self = this;
require('fs').readdir('.', function(err, files) {
if (err)
return self.emit('error', err);
self.files = files;
self.ready = true;
self.emit('ready');
});
};
module.exports = new Db();
And now I think that's more reasonable:
// db.js
var exports = {init: init};
module.exports = exports;
function init(callback) {
callback = (typeof callback === 'function') ? callback : function() {};
require('fs').readdir('.', function(err, files) {
delete exports.init;
exports.result = files; // that's pretty much what I need,
// so don't mind result slightly differs
// from previous cases
callback(err);
});
}
// main.js
var db = require('./db');
// check for `db.init` presence maybe...
db.init(function(err) {
return err ? console.error('Bad!')
: console.log(db); // It works!
});
What should I pick and why? How bad is such idea in general and my options in particular?
Thanks for feedback.
See Question&Answers more detail:os