webentwicklung-frage-antwort-db.com.de

RxJs Array von Observable to Array

Für eine mit Angular2 in TypeScript geschriebene Webanwendung muss ich mit RxJs Observables arbeiten.
Da ich noch nie zuvor RXJs verwendet habe und ich mit reaktiver Programmierung im Allgemeinen noch nicht vertraut bin, habe ich manchmal Schwierigkeiten, den richtigen Weg zu finden, um bestimmte Dinge zu tun.
Ich stehe jetzt vor einem Problem. wo ich einen Array<Observable<T>> in einen Observable<Array<T>> umwandeln muss.
Ich werde versuchen, es mit einem Beispiel zu erklären:
- Ich habe ein Observable, das mir eine Liste von Users (Observable<Array<User>>) Gibt.
- Die Klasse User- hat eine Funktion getPosts, die einen Observable<Array<Post>> Zurückgibt.
- Ich muss den Observable<Array<User>> Einem Observable<Array<Post>> Zuordnen, um alle Posts innerhalb der onNext -Funktion auszuwerten.

Ich kann leicht von Observable<Array<User>> Zu Observable<Array<Observable<Array<Post>>>> Mit abbilden
map((result : Array<User>) => result.map((user : User) => user.getPosts()))
und ich kann einen Array<Array<Post>> zu einem Array<Post> verflachen.
Ich kann jedoch nicht den richtigen Weg finden, um den Observable<Array<Observable<Array<Post>>>> In einen Observable<Array<Array<Post>>> Abzubilden.
Bisher habe ich die Funktion combineLatest zusammen mit flatMap verwendet.
Für mich schien es zu funktionieren und der von mir verwendete Editor (Atom-Editor) zeigte keinen Fehler. Jetzt verwende ich jedoch Netbeans, was mir einen Fehler in diesem Code anzeigt. Auch das Kompilieren des Codes mit "tsc" führt zu Fehlern.
Das sieht so aus:

Argument of type '(result: Post[]) => void' is not assignable to parameter of type 'NextObserver<[Observable<Post>]> | ErrorObserver<[Observable<Post>]> | CompletionObserver<[...'.
Type '(result: Post[]) => void' is not assignable to type '(value: [Observable<Post>]) => void'.  

Meine Frage lautet also:
Wie kann ich ein Array von Observables in ein Array "verflachen"?

22
Springrbua

Der Operator flatMap erlaubt dies. Ich verstehe nicht ganz, was Sie versuchen, aber ich versuche, eine Antwort zu geben ...

Wenn du alles laden willst 

getPostsPerUser() {
  return this.http.get('/users')
    .map(res => res.json())
    .flatMap((result : Array<User>) => {
      return Observable.forkJoin(
        result.map((user : User) => user.getPosts());
    });
}

Mit Observable.forkJoin können Sie warten, bis alle Observables Daten erhalten haben.

Der obige Code setzt voraus, dass user.getPosts() eine beobachtbare ...

Damit erhalten Sie ein Array von Beiträgen:

this.getPostsPerUser().subscribe(result => {
  var postsUser1 = result[0];
  var postsUser2 = result[1];
  (...)
});
27

Sie können die Funktion auf die gewünschte rxjs-Methode anwenden:

const source1 = Rx.Observable.interval(100)
  .map(function (i) { return 'First: ' + i; });

const source2 = Rx.Observable.interval(150)
  .map(function (i) { return 'Second: ' + i; });

const observablesArray = [source1, source2];

const sources = Rx.Observable.combineLatest
.apply(this, observablesArray).take(4)

/* or you can write it without "apply" this way:
const sources = Rx.Observable
                .combineLatest(...observablesArray)
                .take(4)
*/
sources.subscribe(
  (response) => {
    console.log(response);
  }
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>

7
Julian FARHI

Verwenden Sie ForkJoin für dieses Array von Observables, dann ist es ein Observable des Arrays.

1
r ne

Hier ist ein Beispielcode, der [email protected] verwendet

import { of, forkJoin} from 'rxjs';
import { Observable } from 'rxjs'

const source:Array<Observable<String>> = [of('A'), of('B'), of('C') ];

forkJoin(source).subscribe( (x)=> console.log(x))

https://arrayofobservablesexamp.stackblitz.io

0