J'ai un BehaviorSubject
que j'aimerais pouvoir filtrer
, mais je maintiens une qualité semblable à un sujet de comportement que les nouveaux abonnés obtiennent toujours une valeur lorsqu'ils abonnez-vous, même si la dernière valeur émise a été filtrée. Existe-t-il un moyen succinct de le faire en utilisant les fonctions intégrées de rxjs? Par exemple:
const isEven = (n) => n % 2 === 0; const source = new BehaviorSubject(1); const stream = source.pipe(filter(isEven)); stream.subscribe((n) => console.log(n)); // <- I want this to print `1` source.next(2); // prints `2`; that's good source.next(3); // does not print anything; that's good
J'ai écrit ma propre implémentation, mais je préférerais une solution plus simple utilisant des opérateurs existants à la place si c'est facile.
3 Réponses :
Votre flux
a déjà été redirigé pour utiliser le filtre isEven
, donc votre valeur initiale de 1 ne s'affiche pas dans votre console se comporte comme prévu.
Si vous voulez voir votre valeur initiale de 1, abonnez-vous directement au BehaviourSubject
:
const isEven = (n) => n % 2 === 0; const source = new BehaviorSubject(1); const stream = source.pipe(filter(isEven)); // should print 1, and should print 2 and 3 when your source is nexted. source.subscribe((n) => console.log(n)); stream.subscribe((n) => console.log(n)); // <- should NOT Print 1, because it has been filtered source.next(2); // prints `2`; that's good source.next(3); // does not print anything; that's good
Désolé, je ne dois pas bien formuler ma question. Je sais que c'est pourquoi il se comporte différemment, je veux savoir comment le faire se comporter de cette façon. Je veux savoir comment construire le stream
de telle sorte qu'il imprime les choses aux moments que j'ai listés. Je reviendrai pour essayer de reformuler la question.
Utilisez simplement un deuxième BehaviorSubject
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
const { BehaviorSubject } = rxjs; const { filter} = rxjs.operators; const isEven = (n) => n % 2 === 0; const source = new BehaviorSubject(1); const stream = new BehaviorSubject(source.getValue()); source.pipe(filter(isEven)).subscribe(stream); stream.subscribe(val => { console.log(val); }); source.next(2); source.next(3);
OK, c'est assez simple. Cool. Je pense que la partie centrale pourrait être simplifiée en source.pipe (filter (isEven)). Subscribe (stream)
, aussi.
J'ai réalisé qu'après avoir quitté le travail, il était tard un vendredi après-midi et l'heure de la bière m'appelait.
Comment feriez-vous cela de telle manière que si le filtre est faux, stream
se voit attribuer une valeur par défaut au lieu de simplement ne pas obtenir une nouvelle valeur du tout?
Il semble que je devrais utiliser map
au lieu de filter
(pardonnez ma nouveauté à RxJS)
La réponse d'Adrian obtient le crédit, il semble qu'il répond de la meilleure façon étant donné les opérateurs intégrés disponibles avec rxjs
lui-même. Cela ne répondait pas tout à fait à mes besoins, j'ai donc publié mon opérateur personnalisé dans ma petite bibliothèque s-rxjs-utils
. Il s'appelait filterBehavior ()
< / a>. À partir de la documentation:
Fonctionne comme
filter ()
, mais laisse toujours passer la première émission pour chaque nouvel abonné. Cela le rend approprié pour les abonnés qui s'attendent à ce que l'observable se comporte comme unBehaviorSubject
, où la première émission est traitée de manière synchrone lors de l'appel àsubscribe ()
(comme leasync
pipe dans un modèle angulaire).