2016-05-20 7 views
2

Beispiel:Asynchronous Laden von Daten in Klassenkonstruktors

var readBackend = function(){ 
    var deferred = q.defer(); 
    readData().then(function(data) { 
     deferred.resolve(data); 
     }) 
    return deferred.promise; 
} 

class Test { 
    constructor(){ 
     readBackend().then(function(data) { 
      this.importantData = data; 
     }) 
    } 

    someFunc() { 
     //iterate over important data, but important data is defined 
     //promise didnt resolved yet 
    } 

} 

var test = new Test(); 
test.someFunc(); //throws exception! 

Gibt es eine Möglichkeit, um sicherzustellen, dass die Objekteigenschaften durch Konstruktor initiiert werden, wenn ich someFunc nennen?

Der einzige Weg, die mir in den Sinn kommt init Funktion schafft, das Versprechen zurück, aber dann, jedes Mal wenn ich meine Klasse zu verwenden, würde ich auf init-Funktion verlassen richtig

+0

[Laden Sie keine asynchronen Daten in Ihren Konstruktor] (http://stackoverflow.com/q/24398699/1048572). – Bergi

Antwort

5

Gibt es eine Möglichkeit zu arbeiten, um sicherzustellen, dass Objekteigenschaften von Konstruktor initiiert werden, wenn ich someFunc aufrufen?

Nicht ohne Umstrukturierung Ihres Codes. Sie können nicht zulassen, dass Ihr Konstruktor asynchrone Operationen ausführt und erwarten, dass Ihre synchronen Methoden funktionieren.


Ich sehe zwei mögliche Lösungen:

1. eine statische Methode haben, die die Daten geladen und gibt eine neue Instanz der Klasse:

class Test { 
    static createFromBackend() { 
     return readBackend().then(data => new Test(data)); 
    } 

    constructor(data){ 
     this.importantData = data; 
    } 

    someFunc() { 
     // iterate over important data 
    } 
} 

Test.createFromBackend().then(test => { 
    test.someFunc(); 
}); 

Dies stellt sicher, dass die Daten verfügbar sind Wenn die Instanz erstellt wurde, können Sie die API der Klasse synchron halten.

2. Bewahren Sie das Versprechen auf das Objekt:

class Test { 
    constructor(){ 
     this.importantData = readBackend(); 
    } 

    someFunc() { 
     this.importantData.then(data => { 
     // iterate over important data 
     }); 
    } 
} 

Natürlich, wenn someFunc soll etwas zurückgeben, die es erfordern würde auch ein Versprechen zurückzukehren. I.e. Die API Ihrer Klasse ist jetzt asynchron.