web-dev-qa-db-fra.com

RxJS 6 - Annuler / terminer un tuyau

Travailler avec la nouvelle version de RxJS 6 et l'opérateur de tuyau en particulier. Utilise actuellement le canal pour prendre les résultats d'un appel d'API et les transmettre à une série de tâches supplémentaires.

Tout fonctionne très bien, mais je n'arrive pas à trouver un moyen d'annuler ou de terminer un tuyau si je rencontre un problème. Par exemple, j'utilise l'opérateur tap pour vérifier si la valeur est nulle. Je lance ensuite une erreur, mais le tuyau semble toujours passer à la tâche suivante, dans ce cas concatmap.

Par conséquent, comment terminer ou annuler un tuyau prématurément? Merci d'avance.

getData(id: String): Observable<any[]> {
return this.http.get<any>(`${this.baseUrl}/path/${id}`).pipe(
   tap(evt => {
    if (evt == null) {
      return throwError(new Error("No data found..."));
    }
  }),
concatMap(
  evt =>
     <Observable<any[]>>(
        this.http.get<any[]>(
    `${this.baseUrl}/path/relatedby/${evt.child_id}`
      ).map(res =>( {"response1":evt, "response2":res}) )
 )
),
retry(3),
catchError(this.handleError("getData", []))
);}
11
RookieMcRookie

J'ai essayé le concept de base de ce que vous avez avec ce stackblitz et cela a fonctionné. Il a annulé les opérations restantes. Voir le lien ci-dessous.

https://stackblitz.com/edit/angular-4ctwsd?file=src%2Fapp%2Fapp.component.ts

Les différences que je vois entre votre code et le mien sont que j'ai utilisé throw et non throwError (est-ce quelque chose que vous avez écrit?) Et je lance juste l'erreur ... ne renvoie pas une erreur levée .

Voici le code de référence:

import { Component } from '@angular/core';
import { of, from } from 'rxjs';
import { map, catchError, tap, retry} from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular 6';

  constructor() {
    of('a', 'b', 'c', 'd')
      .pipe(
       map(x => {
        if (x === 'c') {
          throw 'An error has occurred';
        }
        return x;
       }),
       tap(x => console.log('In tap: ', x)),
       retry(3),
       catchError(() => of('caught error!'))
      )
      .subscribe(x => console.log(x));
  }
}
3
DeborahK

Vous pouvez également annuler/terminer un canal en utilisant un signal Subject et l'opérateur rxjs: takeUntil

Exemple

httpGetSafe(path: string): Observable<Data> {
  const stopSignal$ = new Subject();

  return this.http.get<Data>(path).pipe(
    map(data => {
      const isBad = data === null;
      if (isBad) {
        stopSignal$.next();
      }
      return data;
    }),
    takeUntil(stopSignal$)
  );
}

Parfois, c'est un peu plus simple et plus flexible que de lancer des erreurs ...

1
Ben Winding