我如何最好地处理以下情况?
我有一个构造函数,需要一些时间才能完成。
var Element = function Element(name){ this.name = name; this.nucleus = {}; this.load_nucleus(name); // This might take a second. } var oxygen = new Element('oxygen'); console.log(oxygen.nucleus); // Returns {}, because load_nucleus hasn't finished.
我看到了三个选项,每个选项似乎都与众不同。
一种 ,向构造函数添加回调。
var Element = function Element(name, fn){ this.name = name; this.nucleus = {}; this.load_nucleus(name, function(){ fn(); // Now continue. }); } Element.prototype.load_nucleus(name, fn){ fs.readFile(name+'.json', function(err, data) { this.nucleus = JSON.parse(data); fn(); }); } var oxygen = new Element('oxygen', function(){ console.log(oxygen.nucleus); });
第二 ,使用EventEmitter发出“已加载”事件。
var Element = function Element(name){ this.name = name; this.nucleus = {}; this.load_nucleus(name); // This might take a second. } Element.prototype.load_nucleus(name){ var self = this; fs.readFile(name+'.json', function(err, data) { self.nucleus = JSON.parse(data); self.emit('loaded'); }); } util.inherits(Element, events.EventEmitter); var oxygen = new Element('oxygen'); oxygen.once('loaded', function(){ console.log(this.nucleus); });
或三 ,阻止构造函数。
var Element = function Element(name){ this.name = name; this.nucleus = {}; this.load_nucleus(name); // This might take a second. } Element.prototype.load_nucleus(name, fn){ this.nucleus = JSON.parse(fs.readFileSync(name+'.json')); } var oxygen = new Element('oxygen'); console.log(oxygen.nucleus)
但我以前从未见过任何完成的事情。
我还有什么其他选择?
鉴于有必要避免在Node中进行阻塞,事件或回调的使用并不奇怪(1)。
稍加修改为2,即可将其与One合并:
var Element = function Element(name, fn){ this.name = name; this.nucleus = {}; if (fn) this.on('loaded', fn); this.load_nucleus(name); // This might take a second. } ...
不过,就像fs.readFile您的示例中一样,核心Node API(至少)通常遵循静态函数的模式,这些静态函数会在数据准备就绪时公开实例:
fs.readFile
var Element = function Element(name, nucleus) { this.name = name; this.nucleus = nucleus; }; Element.create = function (name, fn) { fs.readFile(name+'.json', function(err, data) { var nucleus = err ? null : JSON.parse(data); fn(err, new Element(name, nucleus)); }); }; Element.create('oxygen', function (err, elem) { if (!err) { console.log(elem.name, elem.nucleus); } });
(1)读取JSON文件应该不需要很长时间。如果是这样,则可能是为了更改数据而更改了存储系统。