2017-06-26 2 views
2

Ich versuche, den Wert der versprochenen Rückgabe an eine Variable zuzuweisen, aber es wird nicht zugewiesen. Ich bekomme immer noch leere Zeichenfolge, wenn ich console.log (this.imageref1). Ziel ist es, die Datei data.downloadURL abzurufen, die nach dem Hochladen des Fotos in den Firebase zurückgegeben wird. Ich brauche die heruntergeladene URL. um es in meiner Datenbank für den Bildpfad zu speichern. Ich stecke hier fest, meine Datenbank bekommt leere Daten für die DownloadURL.Promise-Rückgabedaten können der Klassenvariablen nicht zugewiesen werden?

post_news(form: NgForm){ 

    this.title = form.value.title; 
    this.content = form.value.content; 
    this.category = form.value.category; 


    console.log(this.capturedimage1); 


    if(this.capturedimage1 !== ''){ 

     //console.log('captured image is not empty'); 



    let storageRef = firebase.storage().ref(); 

    const filename = Math.floor(Date.now()/1000); 

    const imageRef = storageRef.child(`images/${filename}.jpg`); 

    let uploaded_file_path = `images/${filename}.jpg`;  


    imageRef.putString(this.capturedimage1, firebase.storage.StringFormat.DATA_URL).then(data=>{ 

     this.imageref1 = data.downloadURL; 

    }); 


    } 
} 

Antwort

1

So wird dieser Wert gesetzt zu werden - schließlich. Wahrscheinlich haben Sie mit der Tatsache zu kämpfen, dass es passiert, nachdem die umschließende Funktion ausgeführt wurde. Zum Beispiel hier ist ein wirklich einfacher Testfall:

function test(x) { 
    x.a = 1; 
    Promise.resolve(true).then(_ => x.b = 2); 
    console.log(x); 
} 

Der Betrieb,

> test({c: 3}) 
{ c: 3, a: 1 } 
undefined 

protokolliert ein Objekt, das noch nicht b: 2 drin hat, dann kehrt undefined. Dieser Parameter wird eingestellt, natürlich, schließlich:

> test(abc = {c: 3}) 
{ c: 3, a: 1 } 
undefined 
> abc 
{ c: 3, a: 1, b: 2 } 

Um zu verstehen, was wirklich vor sich geht, müssen Sie verstehen, dass alle JS im Fall „Ereignisschleife.“ JavaScript lässt nur eine Sache gleichzeitig zu. Wenn Sie also andere Ereignisse planen, muss JS der Regel folgen: "Führen Sie zuerst alles in dieser Funktion durch und suchen Sie dann nach etwas anderem, das geplant wurde."

Einige Funktionsaufrufe passieren synchron, sie den Funktionsaufruf blockieren, vorwärts zu bewegen, bis sie abgeschlossen ist. Beispiel: [1,2,3].forEach(x => console.log('hello, ' + x)) protokolliert vor dem Abschluss 3 Zeichenfolgen an der Konsole. Aber der ganze Punkt eines versprochenen Werts ist, dass der Computer damit beschäftigt ist, es herauszufinden, es ist noch nicht verfügbar. Daher können Sie nur den Wert tatsächlich benutzen, wenn sie herausgefunden hat, und alle Ihre Manipulationen des Versprechen einschließlich Zugabe eines Zuhörers zu .then() oder .catch() sind asynchrone oder non-blocking. Die aktuelle Funktion wird abgeschlossen, und diese Rückrufe werden in die Ereignisschleife eingefügt, sobald die versprochene Berechnung abgeschlossen ist.

+0

Thxx für Ihre Antwort Kumpel !. Ohh das bedeutet, was auch immer in der. Thhen ({. ..wird den Fluss der Funktion nicht blockieren, richtig? um das zu erzwingen. Dann ({Funktion, um im Fluss der gesamten Funktion zu sein, muss ich diese ganze Sache setzen 'imageRef.putString (this.capturedimage1, firebase.storage. StringFormat.DATA_URL) .dann (data => {that.imageref1 = data.downloadURL;}); 'zu einer Funktion? – Mikethetechy

+0

@Mikethetechy: Sie * kann * nicht von asynchron zu synchron gehen. Die Laufzeit sagt: "Ich werde nicht damit aufhören", und es gibt keine Möglichkeit, es reinzulegen, "nein, eigentlich wirst du damit aufhören." Wenn Sie sich noch in der Funktion befinden, in der das Versprechen definiert wurde, hat der Rückruf * noch nicht ausgelöst * und * wird nicht ausgelöst *: Er wird später geplant. Sie müssen asynchron über das gesamte Programm nachdenken, wenn ein Teil davon ist, also setzen Sie irgendwelche Datenbank-einfügen-whatevers in den '.then()' Callback zu passieren, wenn Sie diesen Wert kennen, anstatt zu versuchen, es zu tun, bevor Sie wissen . –

+0

thx für Ihre Antwort ... jetzt bekomme ich, wie asynchrone Funktionen funktionieren..so die einzige Möglichkeit für mich, die Datenbank einfügen ist in der. Then() -Rückruf. aber ich habe eine Liste von Bildern, nachdem ich sie hochgeladen habe, ich muss die Download-URL erhalten, um die Download-URL in der Datenbank zu speichern .... es ist ziemlich herausfordernd ... egal, welche Art und Weise ich versuche, ich muss immer noch die Download-URL .. . – Mikethetechy

1
var that = this; 
imageRef.putString(this.capturedimage1, firebase.storage.StringFormat.DATA_URL) 
.then(data=>{  
    that.imageref1 = data.downloadURL; 
    return Promise.resolve(data.downloadURL); 
}) 
.then(function(url){ 
    //make the db call. 
}); 
+0

thx für deine Antwort ... also heißt das, ich kann smthng so machen: var tmp_url = ''; imageRef.putString (this.capturedimage1, firebase.storage.StringFormat.DATA_URL) .dann (data => {tmp_url = data.downloadURL;}); this.bildref1 = tmp_url? – Mikethetechy

+0

@cr-Drost wies darauf hin, die dann teilweise Ausführung geschieht aysnc. Der Code innerhalb des then-Blocks könnte zu einem späteren Zeitpunkt ausgeführt werden. In diesem Fall könnte also this.imageref1 = tmp_url vor dem then-Block ausgeführt werden, sodass es möglicherweise nicht zu dem erwarteten Ergebnis führt. – gvmani

+0

also gibt es keine Möglichkeit, dass ich es synchronisieren kann? – Mikethetechy

Verwandte Themen