web-dev-qa-db-fra.com

RXJS Combinaison de plusieurs observables à l'intérieur d'un tuyau

J'ai un appel d'API qui renvoie une certaine quantité d'identifiants. Chacun de ces identifiants est utilisé pour effectuer un nouvel appel API. Les résultats de ces appels d'API doivent être combinés en un seul objet.

Au début, j'ai utilisé une boucle à l'intérieur de l'opérateur .pipe (map) du premier appel api. Dans cette boucle, j'ai fait les deuxièmes appels api, et dans l'opérateur .pipe (map) dans chacun de ces appels, j'éditerais une variable dans mon composant angular.

Ce n'était pas très joli, et je me demandais si c'était sûr pour les threads. Je sais que javascript est un thread unique, mais il ne semble pas très sûr d'avoir plusieurs processus asynchrones jouant avec la même variable globale.

après cela, je viens de stocker l'observable retourné par le deuxième appel api dans un tableau en bouclant sur les ID retournés par apiCall1, et j'ai utilisé forkJoin pour souscrire et gérer chaque résultat en conséquence (voir l'exemple).

Ce n'est pas très joli cependant, et je me demandais s'il y avait un opérateur que je peux utiliser dans ma pipe pour ça?

Donc au lieu de (pseudocode):

  .pipe(
      map(ids=> {

        let observables = []
        for (const id of ids) {
         observables.Push(this.service.getSomeStuff(id));
        }

        forkJoin(...observables).subscribe(dataArray) => {
          for (data of dataArray) {
            //Do something
          }
        });

      }),
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
        return throwError(error);
      })
    )
    .subscribe();

Y a-t-il un opérateur qui en fait quelque chose comme ceci:

  .pipe(
      map(ids=> {

        let observables = []
        for (const id of ids) {
         observables.Push(this.service.getSomeStuff(id));
        }

      return observables
      }),
      forkJoin(dataArray => {
          for (data of dataArray) {
            //Do something
          }
        });
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
        return throwError(error);
      })
    )
    .subscribe();
5
BartKrul

Au lieu de modifier vos données à la fois en utilisant for, pourquoi ne le faites-vous pas lors de la réception des données? Quelque chose comme ça.

source$.pipe(
  mergeMap(ids => from(ids)),
  mergeMap(id => this.service.getSomeStuff(id)),
  tap(data => //do someting with the data);
  takeWhile(() => this.componentActive),
  catchError(error => {
    console.log(error);
    return throwError(error);
  }),
  toArray(), --> this create the array of all the values received.
)
.subscribe(data => //returns array of modified data);
0
emkay