Note that there are some explanatory texts on larger screens.

plurals
  1. POAsynchronous initialization of Node.js module
    text
    copied!<p>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 <code>./</code> will do for brevity.</p> <p>I can't export function or class because I need <code>require('db')</code> to return same object everytime.</p> <hr/> <p><strong>First</strong> and simplest what came to my mind is to assign <code>module.exports</code> to <code>Object</code> and populate it later:</p> <pre class="lang-js prettyprint-override"><code>var exports = {}; module.exports = exports; require('fs').readdir('.', function(err, files) { exports.error = err; exports.files = files; }); </code></pre> <p>Bad thing — I don't really know from outside when list is ready and no good way to check for errors.</p> <hr/> <p><strong>Second</strong> way I've comed up with is to inherit <code>EventEmitter</code> and notify everyone that DB is ready or error occured. If everything ok - keep going.</p> <pre class="lang-js prettyprint-override"><code>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(); </code></pre> <hr/> <p>And <strong>now</strong> I think that's more reasonable:</p> <pre class="lang-js prettyprint-override"><code>// 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); }); } </code></pre> <pre class="lang-js prettyprint-override"><code>// 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! }); </code></pre> <hr/> <p>What should I pick and why? How bad is such idea in general and my options in particular?</p> <p>Thanks for feedback.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload