筛选一个BehaviorSubject

时间:2019-04-05 00:36:55

标签: rxjs

我有一个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

我已经编写了自己的实现,但是如果容易的话,则宁愿使用现有运算符来获得更简单的解决方案。

3 个答案:

答案 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管道) )。