javascript - RXJS si avec observable comme condition


Je veux utiliser Rx.Observable.if pour exécuter l'un des deux observables si un observable conditionnel se résout à vrai ou faux.

Ce que je veux accomplir ressemblerait à quelque chose comme ceci :

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

Si conditionalObservable envoie un next puis se termine avec une valeur true, firstObservable devrait s'exécuter et sinon, secondObservable devrait s'exécuter.

Maintenant, évidemment, cela ne fonctionne pas parce que Rx.Observable.if s'attend à une fonction conditionnelle, pas à un observable. Comment puis-je obtenir exactement la même fonctionnalité dans RXJS ?

Remarque : Ce problème est presque le même, mais je ne pense pas qu'il soit assez concis parce que 1) vous devez avoir deux instructions pausable et 2) à moins d'ajouter un take(1) à vos observables conditionnels, vous ne pouvez pas garantir que la condition n'émettra pas plus d'événements next. À mon avis, c'est une solution de contournement et elle est sujette à beaucoup plus d'erreurs humaines.

Réponse #1

Si je comprends bien, vous pourriez essayer quelque chose comme ça :

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

J'ai ajouté la partie last parce que vous avez mentionné que vous voulez choisir votre observable (premier ou deuxième) sur la dernière valeur de conditionalObservable.

Je ne suis pas sûr de la valeur de l'opérateur if ici, car il se base sur une valeur scalaire qui doit être produite de manière synchrone par la fonction sélectrice. Donc, à moins d'utiliser cette fonction pour retourner une variable accessible dans une fermeture, et que vous pouvez modifier au moment où votre condition est évaluée, ce n'est pas très utile à mon avis. Et même dans ce cas, votre sélecteur devient une fonction impure, ce qui n'est pas une bonne pratique pour des fins de test et autres.

Réponse #2

Que diriez-vous d'utiliser switch ?

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

Ou flatMapLatest ? Si je comprends bien la documentation, cela fera la même chose que le précédent :

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