我有一个BehaviorSubject
,我希望能够filter
,但保持类似行为主体的性质,即即使新订户最后一个订户也总是能获得价值发出的值被过滤掉。使用rxjs的内置函数可以做到这一点吗?例如:
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
我已经编写了自己的实现,但是如果容易的话,则宁愿使用现有运算符来获得更简单的解决方案。
答案 0 :(得分:1)
只需使用第二个BehaviorSubject
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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
答案 1 :(得分:0)
您的stream
已通过管道传递给isEven
过滤器,因此您的初始值1并未在控制台中显示为预期的状态。
如果要查看初始值1,请直接订阅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
答案 2 :(得分:0)
阿德里安的答案赢得了赞誉,因为他rxjs
本身提供了内置运算符,因此他似乎是最好的答案。它不能完全满足我的需求,因此我在小库s-rxjs-utils
中发布了自定义运算符。它称为filterBehavior()
。从文档中:
的工作方式类似于
filter()
,但始终让每个新订户都能通过首次发射。这使得它适合希望观察到的行为类似于BehaviorSubject
的订户,其中第一次发射是在调用subscribe()
的过程中同步处理的(例如Angular模板中的async
管道) )。