Asynchroner Konstruktor
Wie kann ich am besten umgehen einer situation wie der folgenden?
Ich habe einen Konstruktor, der eine Weile dauert, um abzuschließen.
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.
Sehe ich drei Optionen, von denen jeder scheint sich von den gewöhnlichen.
Einefügen Sie eine callback-Funktion an den Konstruktor.
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);
});
Zweiverwenden Sie EventEmitter ausstrahlen 'geladen' event.
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);
});
Oder dreiblockieren Sie den Konstruktor.
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)
Aber ich habe nicht gesehen, alle dies getan haben, bevor.
Welche anderen Möglichkeiten habe ich?
InformationsquelleAutor der Frage Luke Burns | 2012-08-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Angesichts der Notwendigkeit, zu vermeiden, blockiert bei Knoten, die Verwendung von events und callbacks ist nicht so seltsam,(1).
Mit einem leichten Bearbeiten von Zwei, könnte man zusammenfassen mit:
Obwohl, wie die
fs.readFile
in deinem Beispiel, den core-APIs Knoten (mindestens) oft nach dem Muster von statischen Funktionen, die freizulegen, die Instanz, wenn die Daten bereit sind:(1) Es sollte nicht sehr lange dauern, zu Lesen, dass ein JSON-Datei. Wenn es ist, vielleicht eine änderung im storage-system ist in-Reihenfolge der Daten an.
InformationsquelleAutor der Antwort Jonathan Lonowski
Update 2:
Hier ist ein Aktuelles Beispiel über eine asynchrone factory-Methode. N. B. dies erfordert die Knoten 8 oder Babel, wenn in einem browser laufen.
Update:
Den code unten hab von Ihnen positiv bewertet werden, ein paar mal. Allerdings finde ich diesen Ansatz über eine statische Methode viel besser:
https://stackoverflow.com/a/24686979/2124586
ES6-version mit verspricht
InformationsquelleAutor der Antwort tim
Eine Sache, die Sie tun können, ist preload alle Kerne (vielleicht ineffizient, ich weiß nicht, wie viel Daten es sich handelt). Die anderen, die ich empfehlen würde, wenn Vergleichsseiten ist keine option, das würde einen Rückruf mit einem cache zu speichern geladenen Kerne. Hier ist das Konzept:
InformationsquelleAutor der Antwort Will
Dies ist ein schlechtes code-design.
Das Hauptproblem ist in der callback-Ihr Beispiel ist es nicht noch ausführen des "zurück", das ist, was ich meine
So, die guten code-design, ist der explizite Aufruf der "init" - Methode (oder in deinem Fall "load_nucleus") nach instanziert die Klasse
InformationsquelleAutor der Antwort Simone Sanfratello
Habe ich entwickelt einen asynchronen Konstruktor:
mein 1. iteration war:
vielleicht fügen Sie einfach einen Rückruf
Anruf einer anonymen async-Funktion,
dann rufen Sie die callback.
mein 2. iteration war:
versuchen wir mit einem Versprechen statt einer callback.
Ich dachte mir: seltsam, ein Versprechen der Rückkehr ein Versprechen, und es funktionierte. .. so, die nächste version ist nur ein Versprechen.
callback-basiert für die alten javascript -
InformationsquelleAutor der Antwort Shimon Doodkin
Können Sie laufen Konstruktor-Funktion mit asynchronen Funktionen synchron über nsynjs. Hier ist ein Beispiel zur Verdeutlichung:
index.js (Haupt-app-Logik):
MyObject.js (definition der Klasse mit langsamen Konstruktor):
wrappers.js (nsynjs-bewusst wrapper um die langsamen Funktionen mit callbacks):
Vollständigen Satz von Dateien für dieses Beispiel könnte hier gefunden werden: https://github.com/amaksr/nsynjs/tree/master/examples/node-async-constructor
InformationsquelleAutor der Antwort amaksr