2017-07-27 3 views
0

Im Arbeiten mit Observablen und dem Operator flatMap habe ich eine Methode geschrieben, die eine Observable mit einem Array von Objekten aufrufen und zurückgeben kann. Was ich eigentlich brauche, ist, diese Anordnung von Objekten zu erhalten und jedes Objekt zu verarbeiten. Nachdem alle Elemente verarbeitet sind, möchte ich das Ergebnis verketten, um einen zusätzlichen API-Aufruf mit einer anderen Methode, die ich geschrieben habe, zu machen. Der folgende Code tut, was ich brauche:Verketten von Observablen mit flatMap

this.apiService.getInformation('api-query', null).first().flatMap((apiData) => { 
    return apiData; 
    }).subscribe((dataObject) => { 
    this.processService.processFirstCall(dataObject); 
    }, null,() => { 
    this.apiService.getInformation('another-query', null).first().subscribe((anotherQueryData) => { 
     this.processService.processSecondCall(anotherQueryData); 
    }); 
    }); 

Aber dieser Ansatz ist nicht optimal aus meiner Sicht, würde Ich mag Kette tun, diese Anrufe flatMap verwenden, aber wenn ich folgendes tun

this.apiService.getInformation('api-query', null).first().flatMap((apiData) => { 
    return apiData; 
    }).flatMap((dataObject) => { 
    this.processService.processFirstCall(dataObject); 
    return [dataObject]; 
    }).flatMap((value) => { 
    return this.apiService.getInformation('another-api-query', null).first(); 
    }).subscribe((value) => { 
    this.processService.processSecondCall(value); 
    }); 

Die Der zweite API-Aufruf wird für jedes Element im apiData-Array von Objekten einmal ausgeführt. Ich weiß, dass ich vermisse oder etwas falsch verstehe. Aber von der zweiten Antwort dieses Threads Why do we need to use flatMap? Ich denke, dass die zweite FlatMap die verarbeiteten apiData zurückgegeben werden soll, stattdessen gibt jedes der Objektelemente auf diesem Array zurück. Ich würde die Hilfe zu schätzen wissen.

Vielen Dank.

Antwort

0

Das Problem, das ich Ihr Begegnungs denken ist, dass flatmap zu einer beobachtbaren oder Versprechen angewandt werden soll. In Ihrem zweiten Codebeispiel geben Sie Daten innerhalb des Flatmap-Operators zurück, der dann an die folgenden Flatmap-Funktionen übergeben wird, während diese Observables zurückgeben sollten. Zum Beispiel:

this.apiService.getInformation('api-query', null).first() 
    .flatMap((dataObject) => { 
    return this.processService.processFirstCall(dataObject); 
    }).flatMap((value) => { 
    return this.apiService.getInformation('another-api-query', null) 
    }).subscribe((value) => { 
    this.processService.processSecondCall(value); 
    }); 

Siehe this post für die weitere Klärung.

3

Was Sie wollen, ist der .do() Operator und nicht flatMap(). flatMap() wird ein Ereignis in ein anderes Ereignis umwandeln und es im Wesentlichen verketten. .do() führt einfach das aus, was Sie ihm anweisen, zu jeder Emission in den Ereignissen.

aus dem Code, gibt es 2 asynchrone Methoden (Anrufe an die api) und 2 synchron (processService). Was Sie tun möchten, ist:

  1. Aufruf an die erste API (async), warten auf die Ergebnisse
  2. Prozess die Ergebnisse (sync)
  3. Aufruf an die zweite API (async), für die warten Ergebnisse zurück
  4. Prozess die Ergebnisse (sync)

daher Ihren Code kommen sollte:

this.apiService.getInformation('api-query', null)//step1 
    .first() 
    .do((dataObject) => this.processFirstCall(dataObject))//step2 
    .flatMap(() => this.apiService.getInformation('another-api-query', null))//step3 
    .first() 
    .do(value => this.processService.processSecondCall(value))//step4 
    .subscribe((value) => { 
     console.log(value); 
    }); 

Ich schrieb in Kommentar die Schritte entsprechend der obigen Liste. Ich habe auch unnötige Betreiber aufgeräumt (wie Ihre erste flatMap ist irgendwie überflüssig). Wenn Sie Ihre Daten transformieren möchten, sollten Sie .map() anstelle von .do() verwenden. Und ich denke, das ist der Ort, wo Sie mit .map() und .flatMap() verwirrt sind.