【问题标题】:Take items from observable when other observable is true当其他可观察对象为真时,从可观察对象中获取项目
【发布时间】:2021-12-28 16:14:03
【问题描述】:

如何根据另一个可观察的 b 的(布尔)值来控制通过可观察的 a 推送哪些项目?

我的意思是,只有当 b 发出的最后一个项目为真时,才会推送 a 中的项目。

可观察序列 b 应该像一个通过过滤器。

【问题讨论】:

    标签: c# .net observable system.reactive


    【解决方案1】:

    好的,我想我至少有一个解决方案 可以通过WithLatestFromWhere 的组合来完成。

    在我的真实代码中,我有这个:

    • 视频中可观察到的位置
    • 可观察的布尔值,指示用户是否已开始“搜索”操作(通过在视频播放器中任意拖动拇指)
    positionObs
       .WithLatestFrom(isSeekingObs, (pos, isSeeking) => new { pos, isSeeking })
       .Where(x => !x.isSeeking)
       .Select(x => x.pos);
    

    它必须结合两个最近的值并对“信号器”应用过滤器。

    无论如何,我想知道是否有更清洁的解决方案。

    【讨论】:

    • 使用CombineLatest 如果布尔控制序列切换过于频繁,您可能会得到重复。我认为WithLatestFrom 是您所需要的。
    • 感谢@TheodorZoulias!我已经更新了答案。它就像一个魅力 + 这是我第一次使用该运算符。
    【解决方案2】:

    我更喜欢使用PublishSwitch 的组合。

    方法如下:

    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 状态时。我想这在某些情况下可能是可取的。
    • @TheodorZoulias - 是的,因为Publish
    • 您可以查看this fiddle。 A 序列的成功完成永远不会通过 C 序列传播。 A 序列的失败仅在稍后通过 C 序列传播,此时 B 序列发出 true。取消注释.Concat(Observable.Throw... 行以测试失败案例。
    • 这对我来说似乎是一个错误。它应该停止。
    • 为什么? observable_c 基于observable_b,而不是observable_aobservable_a 已发布这一事实并不重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多