javascript - Olika Pipe Baserat på Filter RxJS


Jag har följande problem. Jag vill prenumerera på en observable med hjälp av async-pipen i Angular. Men datan i pipen kan komma från olika datakällor och pipen kan se olika ut beroende på datakällan.

Sättet det implementeras på nu fungerar inte, eftersom jag skriver över det första värdet av this.data$ och därför blir aldrig källa A prenumererad på.

Är det möjligt att 'dela' röret beroende på ett filter?

problem.component.ts:

// Data source A and logic A 
this.data$ = this.service.context.pipe(
  filter(context => context.flag === true),
  switchMap(context => this.dataSourceA(context.id))
  map(data => this.processDataA(data))
);

// Data source B and logic B 
this.data$ = this.service.context.pipe(
  filter(context => context.flag === false),
  switchMap(context => this.dataSourceB(context.id))
  map(data => this.processDataB(data))
);

problem.component.html

<pro-table [data]="data$ | async"></pro-table>

Svar #1

Flytta logiken till din switchMap()

this.data$ = this.service.context.pipe(
   switchMap(context => context.flag
      ? this.dataSourceA(context.id).pipe(map(d => this.processDataA(d)))
      : this.dataSourceB(context.id).pipe(map(d => this.processDataB(d)))
   )
);

Svar #2

Det är bara fel sätt att uppnå det resultat du önskar. Du måste ta till något som kallas för "högre ordningens observerbar": Observable<Observable<T>>. Liksom en "högre ordningens funktion" (som kan producera en annan funktion baserat på dess argument), kan denna producera en annan Observable baserat på vilken parametrisering du förlitar dig på.

this.service.context.pipe(
  switchMap(context => context.flag ? this.dataSourceA(context.id).pipe(...) : this.dataSourceB(context.id).pipe(...))
);

...det kan verka lite esoteriskt i början, men egentligen är det det inte. \

P.S. Viktig punkt att komma ihåg: högre ordningens observabler låter dig parametrisera dina strömmar på ett elegant sätt: genom att hantera strömmar av strömmar.

Relaterade artiklar