动态过滤rxjs流

时间:2016-11-10 17:15:55

标签: typescript rxjs rxjs5

我正在使用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

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

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

您的实施中的主要问题是,numberFilterBehaviorSubject,每次订阅时都会发出默认值(在这种情况下为5numberFilter.subscribe(newFilter => ...。此回调订阅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

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