web-dev-qa-db-fra.com

RxJS: observable d'un tableau pour un tableau d'observables

J'ai la situation suivante en utilisant Observables dans mon application Angular4 et je ne peux tout simplement pas me rendre au travail: je souhaite collecter des données récapitulatives sur tous mes jours de réservation pour une page d'aperçu. Obtenir tous les jours est un observable, et chaque jour contient une liste des réservations de ce jour-là que je dois récupérer - à nouveau une source observable. À partir de cette liste, je calcule un résumé de la journée. Tous ces résumés que je veux émettre dans un résultat observable.

J'ai essayé beaucoup de choses plus compliquées, mais toujours les observables internes n'étaient pas attendues pour terminer et j'ai des résumés vides. Je suis revenu à la base, et quelque chose dans ce sens devrait marcher:

getSummaries(): Observable<BookingDaySummary[]> {
    return this.bookingService.getBookingDays().take(1).mergeMap(
        days => this.calculateSummaryOfDays(days)
    )
};

private calculateSummaryOfDays(days: BookingDay[]): Observable<BookingDaySummary[]> {
    const summaries$ = days.map(day => this.calculateSummary(day));
    // I'm aware that the next line is not correct. 
    // Essentially I want the array of observables to complete 
    // and have an array of the resulting values.
    return Observable.merge(summaries$);
}

private calculateSummary(day: BookingDay): Observable<BookingDaySummary> {
    // ... logic to get summary from one day
}

Cependant, le type de summaries$ est Observable<Observable<BookingDaySummary> et non observable. Tout se résume donc à: Comment créer un Observable<T[]> à partir de [Observable<T>]?

En outre: la méthode la plus interne que j'utilise dans .map doit-elle renvoyer un observable ou simplement une carte du type entrant à T lorsque vous souhaitez produire un Observable<T>?

5
EluciusFTW

Utilisez la fonction statique combineLatest de RxJS sur votre dernière instruction de calculateSummaryOfDays:

return Observable.combineLatest(summaries$);

Notez que votre summaries$ est un tableau d'observables:

const summaries$: Observable<BookingDaySummary>[] = ...

De la combineLatest documentation :

Combine plusieurs observables pour créer un observable dont les valeurs sont calculées à partir des dernières valeurs de chacun des observables en entrée.

La version statique de combineLatest accepte soit un tableau d'observables, soit chaque observable peut être mis directement en argument.

Ainsi, cette fonction prendra votre tableau d'observables et retournera un observable d'un tableau.

2
Richard Johnson

Comment créer un <T []> Observable à partir de <T> []?

forkJoin fait ceci. Utiliser String pour votre T:

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

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

const source2:Observable<String[]> = forkJoin(source);

source2.subscribe((res=>console.log(res)));

https://stackblitz.com/edit/arrayofobs2obsofarray?file=index.ts

1

essayer 

return Observable.from(summaries$).mergeMap(value=>value);

Je suppose que les résumés sont un tableau d'observables - Observable [] Utilise Observable.from les émettra un par un et sera suivi de mergeMap pour aplatir et exécuter l'observable et vous obtiendrez à la fin une émission de valeur normale.

0
Fan Cheung