2017-06-09 6 views
1

Ich habe zwei beobachtbare: obs1 und OBS2Convert Observable <Observable <{t1: T1, T2: T2} >> auf beobachtbare <{t1: T1, T2: T2} []>

  • obs1 ist vom Typ Observable<T1[]> (abgerufen von einer this.service1.getT1Arr() Funktion)
  • OBS2 vom Typ Observable<T2> (von this.service2.getT2(t1: T1) Funktion abgerufen)

Ich möchte eine obs3 mit der Art erstellen:

Observable<{t1: T1, t2: T2}[]> 

Mein aktuelles Problem ist, dass die Funktion, die ich OBS2 als Argument ein Objekt vom Typ T1 abzurufen verwende, also muss ich diese Schritte folgen :

  1. jedes Objekt vom Typ T1 aus dem [] -Array T1 Retrieve
  2. Für
  3. Construct seine entsprechende Objekt jedes T2 dieses Objekt abrufen ein Objekt aus diesen beiden Objekten

Zur Zeit habe ich den folgenden Code:

obs3 = this.service1.getT1Arr().flatMap((t1Arr: T1[]) => { 
    return t1Arr.map((t1) => { 
     return this.service2.getT2(t1).map((t2: T2) => { 
      return { 
       t1: t1 
       t2: t2 
      } 
     } 
    } 
} 

Aber ich habe den Fehler

Observable<Observable<{t1: T1, t2: T2}>> is not assignable to 
Observable<{t1: T1, t2: T2}[]> 

Also meine Frage ist: Wie kann ich meine Array halten während des Prozesses tippen und nicht im Austausch gegen ein Observable verlieren?

Ich sah bereits bei Kombination von Operatoren wie concat(), merge() und auch der Transformationsoperator switchMap() aber das Problem I ist, die ich nicht über zwei Parallelen strömen, aber eine Stream, der aus einem anderen Stream erstellt wird.

Jede Hilfe sehr geschätzt!

+0

Haben Sie versucht, die Signatur spezifisch zu machen? d. h. '.flatMap ((t1Arr: T1 []): Array <{T1, t2}> => {...} ' – Meir

Antwort

1

Das Problem ist, dass flatMap entworfen ist, eine Ebene der Verschachtelung zu reduzieren. Sie haben tatsächlich zwei, weil Sie einen Array von Observables von der Auswahlfunktion zurückgeben. Sie benötigen eine zusätzliche Schicht Abflachung:

const obs3: Observable<{T1, T2}[]> = 
    this.service1.getT1Arr().flatMap((t1Arr: T1[]) => { 
    // Lift the t1Array into an Observable<T1> 
    return Observable.from(t1Array) 
     // Flatten the results of calling service2 
     .concatMap(
     // Returns Observable<T2> 
     t1 => this.service2.getT2(t1), 
     // Use the result selector to map to your desired structure 
     (t1, t2) => ({t1, t2}) 
    ) 
     // Gather the results back up Observable<{T1, T2}[]> 
     .toArray(); 
}); 
+0

Vielen Dank für Ihre schnelle Antwort! Also habe ich es versucht, aber leider funktioniert es nicht. Der Typ ist jetzt dank Ihrer Antwort korrekt, aber wenn ich ihn abonniere, bekomme ich nichts, selbst wenn ich sehe, dass mein t1Arr von Länge 6 ist. Was auch seltsam ist, dass ich anscheinend nur einmal in die concatMap eingebe, während ich eintreten sollte drin 6 mal in meinem Fall (ich habe versucht concatMap durch flatMap zu ersetzen und ich gebe 6 mal wie erwartet ein aber ich habe immer noch kein Ergebnis beim Abonnieren). Weißt du, wo es herkommen könnte? – nothingToBe

+0

Stellen Sie sicher, dass 'getT2() 'und' getT1Arr() 'Observables vollständig sind. Wenn Sie "concatMap" nur einmal eingeben, bedeutet das, dass die inneren Observablen nicht abgeschlossen werden. – paulpdaniels

0

Sie benötigen einen Strom von Listenelementen zu konvertieren einzelner Elemente mit flatMap, dann für jeden Punkt t1, das andere tun fltaMap Anruf t2 zu holen zu streamen. Dann verwenden Sie Karte, um sie zu kombinieren. Prüfen Sie, ob das funktioniert für Sie

this.service1.getT1Arr() 
    .flatMap(t1Arr: T1[] => Observable.from(t1Arr)) 
    .flatMap((t1 : T1)=> this.service2.getT2(t1) 
     .map((t2:T2)=> {t1: t1, t2: t2}) 
    ); 

Wenn Sie das Ergebnis in einzelnen Array erhalten möchten, anstatt Strom Sie .toArray() nach der letzten flatMap hinzufügen können.

Verwandte Themen