Vyhledávání na webu

javascript - RXJS if s observable jako podmínkou


Chci použít Rx.Observable.if k spuštění jednoho ze dvou observables, pokud se podmíněný observable vyhodnotí na true nebo false.

To, čeho chci dosáhnout, by vypadalo nějak takto:

Rx.Observable.if(conditionalObservable.map(x => x.length > 0), firstObservable, secondObservable).subscribe()

Pokud conditionalObservable vyšle hodnotu next a poté dokončí s hodnotou true, měl by být spuštěn firstObservable a jinak by měl být spuštěn secondObservable.

Teď očividně to nefunguje, protože Rx.Observable.if očekává funkci podmínky, ne observable. Jak mohu dosáhnout přesně stejné funkčnosti v RXJS?

Poznámka: Tento problém je téměř stejný, ale nemyslím si, že je dostatečně stručný, protože 1) musíte mít dva příkazy pausable a 2) pokud nepřidáte take(1) ke svým podmíněným observablům, nemůžete zaručit, že podmínka nevygeneruje další next události. Podle mého názoru je to obejití a podléhá mnohem větší lidské chybovosti.

Odpověď č. 1

Pokud tomu dobře rozumím, mohl byste vyzkoušet něco takového:

conditionalObservable.map(x => x.length > 0)
  .last()
  .flatMap(function(condition){
      return condition ? firstObservable : secondObservable});
  .subscribe()

Přidal jsem část last, protože jste zmínil, že chcete vybrat svůj pozorovatelný objekt (první nebo druhý) na poslední hodnotě conditionalObservable.

Nejsem si jistý hodnotou operátoru if zde, protože přepíná na základě skalární hodnoty, která musí být synchronně vyprodukována funkcí selektoru. Takže pokud nepoužijete tuto funkci k vrácení proměnné, která je přístupná v closure a kterou můžete upravit v bodě, kde se vaše podmínka vyhodnocuje, podle mého názoru to není příliš užitečné. A i tehdy se váš selektor stává nečistou funkcí, což není nejlepší postup pro účely testování a podobně.

Odpověď č. 2

Co takhle použít switch?

conditionalObservable
  .map(x => x.length > 0 ? firstObservable : secondObservable)
  .switch()
  .subscribe(...)

Nebo flatMapLatest? Pokud dokumentaci chápu dobře, udělá to totéž co předchozí:

conditionalObservable
  .flatMapLatest(x => x.length > 0 ? firstObservable : secondObservable)
  .subscribe(...)