【发布时间】:2021-12-28 16:14:03
【问题描述】:
如何根据另一个可观察的 b 的(布尔)值来控制通过可观察的 a 推送哪些项目?
我的意思是,只有当 b 发出的最后一个项目为真时,才会推送 a 中的项目。
可观察序列 b 应该像一个通过过滤器。
【问题讨论】:
标签: c# .net observable system.reactive
如何根据另一个可观察的 b 的(布尔)值来控制通过可观察的 a 推送哪些项目?
我的意思是,只有当 b 发出的最后一个项目为真时,才会推送 a 中的项目。
可观察序列 b 应该像一个通过过滤器。
【问题讨论】:
标签: c# .net observable system.reactive
好的,我想我至少有一个解决方案
可以通过WithLatestFrom 和Where 的组合来完成。
在我的真实代码中,我有这个:
positionObs
.WithLatestFrom(isSeekingObs, (pos, isSeeking) => new { pos, isSeeking })
.Where(x => !x.isSeeking)
.Select(x => x.pos);
它必须结合两个最近的值并对“信号器”应用过滤器。
无论如何,我想知道是否有更清洁的解决方案。
【讨论】:
CombineLatest 如果布尔控制序列切换过于频繁,您可能会得到重复。我认为WithLatestFrom 是您所需要的。
我更喜欢使用Publish 和Switch 的组合。
方法如下:
Subject<bool> subject_b = new();
IObservable<bool> observable_b = subject_b.AsObservable();
IObservable<long> observable_a = Observable.Interval(TimeSpan.FromSeconds(1.0));
IObservable<long> observable_c =
observable_a
.Publish(published_a =>
observable_b
.Select(value_b =>
value_b
? published_a
: Observable.Never<long>()))
.Switch();
IDisposable subscription = observable_c.Subscribe(Console.WriteLine);
Thread.Sleep(TimeSpan.FromSeconds(2.5));
subject_b.OnNext(true);
Thread.Sleep(TimeSpan.FromSeconds(3));
subject_b.OnNext(false);
Thread.Sleep(TimeSpan.FromSeconds(4));
subject_b.OnNext(true);
这给了:
2
3
4
9
10
11
12
13
14
...
比起WithLatestFrom,我更喜欢Publish/Switch,因为前者处理的查询种类更多,而后者不处理。
【讨论】:
observable_a 序列完成的即时通知,但如果它发生在控制序列(subject_b)处于false 状态时。我想这在某些情况下可能是可取的。
Publish。
true。取消注释.Concat(Observable.Throw... 行以测试失败案例。
observable_c 基于observable_b,而不是observable_a。 observable_a 已发布这一事实并不重要。