【问题标题】:Dynamically filtering rxjs stream动态过滤 rxjs 流
【发布时间】:2016-11-10 17:15:54
【问题描述】:

我正在使用 RXJS,我正在寻找动态过滤数据,但我遇到了问题:

let numberSource: ReplaySubject<Number> = new ReplaySubject<Number>();
let numberFilter: BehaviorSubject<Number> = new BehaviorSubject<Number>(5);

let filteredData = numberSource.filter(n => n < numberFilter.value);
numberFilter.subscribe(newFilter => {
  filteredData = numberSource.filter(n => n < newFilter);
  filteredData.subscribe(console.log);  // <- I think this is wrong
});

console.log("A");
filteredData.subscribe(console.log);

numberSource.next(1);
numberSource.next(10);
numberSource.next(100);

console.log("B");
numberFilter.next(50);

我正在做的是订阅 numberSource,这是我有兴趣显示的数据。我还订阅了 numberFilter,因为我希望对其进行任何更改以重播主题,但我认为我做错了。

我期待看到:

A
1
B
1
10

我看到了:

A
1
1
B
1
10

谁能帮忙?

【问题讨论】:

  • 首先,我很确定您不应该在每次numberFilter 的订阅者运行时订阅console.logfilterData
  • 你能画出你想要达到的目标吗?该大理石图将有两个输入流和一个输出流。正如所写的那样,代码在流式方面非常笨拙(嵌套订阅是一种不好的做法),而且很难理解你想要做什么
  • @alex 是的,这对我来说似乎也错了!但是,我不确定如何重新启动输出。

标签: typescript rxjs rxjs5


【解决方案1】:

我想我明白你想要做什么。您希望堆叠numberSource 发出的所有值,以便能够在numberFilter 更改时重新发送和过滤它们。

您的实现中的主要问题是numberFilter 是一个BehaviorSubject,它会在您每次订阅它时发出其默认值(在这种情况下为5),这发生在numberFilter.subscribe(newFilter =&gt; ... 行上。此回调订阅filteredData,然后在console.log("A"); 之后再次订阅。因此,您甚至还没有开始向numberSource 发送数据,并且您已经订阅了两次。这就是为什么它会给你两次1

简单的解决方法是使用经典的Subject 并记住unsubscribe() 之前订阅filteredData

let numberSource: ReplaySubject<Number> = new ReplaySubject<Number>();
let numberFilter: Subject<Number> = new Subject<Number>();

var subscription;
numberFilter.subscribe(newFilter => {
  if (subscription) {
    subscription.unsubscribe();
  }

  subscription = numberSource.filter(n => n < newFilter)
    .subscribe(console.log);
});

numberFilter.next(5);

console.log("A");

numberSource.next(1);
numberSource.next(10);
numberSource.next(100);

console.log("B");
numberFilter.next(50);

观看现场演示:http://plnkr.co/edit/vOaD8tcWlLRdfzU14Ufw

现在它会为您提供所需的输出。

【讨论】:

  • 谢谢!是的,这正是我想要做的,你的解决方案确实有效!取消订阅/订阅方法是 rxjs 的惯用方式吗?
  • @DanDan 既然您希望能够重复整个系列数据,那么这似乎是最好的方法。我看不出订阅和取消订阅有什么问题,这就是ReplaySubject的主要目的是能够重复序列。
  • 太棒了,谢谢!仍在努力解决所有这些问题。
猜你喜欢
  • 2017-02-17
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 2021-04-14
  • 1970-01-01
  • 2018-12-17
  • 1970-01-01
相关资源
最近更新 更多