angular - RxJs - Hvordan returnere notifier-verdi med takeuntil-operator


Jeg har en enkel Rxjs-timer som fortsetter å gå til en notifier sender ut noe, veldig grunnleggende så langt.

enum TimerResult = {
    COMPLETE,
    ABORTED,
    SKIPPED
};

_notifier: Subject<TimerResult> = new Subject();
notifier$: Observable<TimerResult> = this._notifier.asObservable();

simpleTimer$ = interval(1000);

startTimer(): Observable<number> <-- **here I want a timerResult** {
  return simpleTimer$.pipe(
      tap(()=>doSomethingBeautifulWhileRunning),
      takeUntil(this.notifier$)
   )

}

Det jeg ønsker å oppnå er å få verdien som blir sendt ut av notifikatoren som et resultat.

Jeg trenger ikke mellomverdier, jeg trenger bare å vite når det fullføres og med hvilket resultat.

simpleTimer$.pipe(
   tap(()=>doSomethingBeautifulWhileRunning),
   last(),
   takeUntil(this.notifier$)
).subscribe((result)=>{
   // Here, of course, I get the last value 
   // I need instead the value coming from notifier$
});

Jeg prøvde mange mulige løsninger med Rx-operatører, men ingen av dem fungerte som forventet. Den eneste jeg fant som ga et akseptabelt resultat (men etter min mening veldig, veldig skittent) var denne:

startTimer(): Observable<TimerResult>{
    simpleTimer$.pipe(...).subscribe(); <-- fire the timer, automatically unsubscribed by takeUntil
    return this.notifier$.pipe(first());
}

Hva er den beste "resept" måten å få tak i dette på? Jeg håper jeg har vært tydelig nok, all hjelp er svært verdsatt :)

Svar #1

Du kan også bruke combineLatest

  startTimer(): Observable<any> {
    const timer$= this.simpleTimer$.pipe(
      tap((res)=>console.log(res)),
      takeUntil(this.notifier$)
    );
    return combineLatest(timer$,this.notifier$)
  }

//and use:
this.startTimer().subscribe(([timer,action])=>{
  console.log(timer,action)
})

se stackblitz

Svar #2

Du kan flette varslingsenheten med den originale strømmen og hente resultatet derfra, prøv eksemplet nedenfor.

const notifier = timer(5000).pipe(mapTo("done"));

merge(interval(1000)
  .pipe(takeUntil(notifier)),
   notifier 
  )
  .subscribe(console.log,null,
   _=>console.log('complete') 
    );

Relaterte artikler