确定并操作一个CombineLatest中最新更新的序列

本文关键字:CombineLatest 最新更新 一个 操作 | 更新日期: 2023-09-27 18:09:12

我想知道是否有一个现有的操作符或一定的逻辑,允许我复制具有2个源序列的CombineLatest的行为,但具有确定最后修改的2个序列中的哪一个的附加能力。反过来,我想使用这个区别来改变我在组合两个序列的最新结果时的操作方式。

我认为表达我想要的一个好方法是通过给出一个方法签名的例子来实现我所说的逻辑。

public static IObservable<TResult> MyOperator<TInLeft, TInRight, TResult>(
    this IObservable<TInLeft> left, 
    this IObservable<TInRight> right, 
    Func<TInLeft, TInRight, bool, TResult> selector)
{
    // ...magic 
} 

在这种情况下,leftright将是入口序列,传递给方法的selector函数将其布尔参数值设置为true,表示left序列是最近更改的来源,false表示right序列是最后更改的来源。

当然,为了清晰起见,该方法也可以按照以下方式重新表述

public IObservable<TResult> MyOperator<TInLeft, TInRight, TResult>(
    this IObservable<TInLeft> left, 
    this IObservable<TInRight> right, 
    Func<TInLeft, TInRight, TResult> whenLeft,
    Func<TInLeft, TInRight, TResult> whenRight)
{
    // ... more magic
} 

其中,不再使用布尔值来区分最近更新的序列,每个序列将以函数的形式具有自己的包含行为。

这样一个操作符的用例是,我想要有一个共享的结果,这个结果依赖于leftright序列的某种组合(就像CombineLatest一样),但是这个优先级给了拥有最新信息的那个。我希望你能明白我的意图。

是否有一个现有的操作符具有类似的底层逻辑或可以适应此目的?不然我怎么能完成这样的行为呢?我对一些可能有用的操作符有一个模糊的概念,但似乎有很多不同的方法,我只是不确定最好的方法来实现我想要的。

确定并操作一个CombineLatest中最新更新的序列

我会这样做:

var combined =
    source1.Timestamp()
        .CombineLatest(source2.Timestamp(), (ts1, ts2) => new { ts1, ts2 });
combined.Select(x =>
    x.ts1.Timestamp < x.ts2.Timestamp
        ? "source1 first"
        : "source2 first");

您可以尝试将Timestamp操作符与CombineLatest结合使用。像这样:

    var obs1 = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp();
    var obs2 = Observable.Interval(TimeSpan.FromSeconds(2)).Timestamp();
    var result = Observable.CombineLatest(obs1, obs2, (v1, v2) =>
    {
        if(v1.Timestamp < v2.Timestamp)
        {
            Console.WriteLine("v1 " + v1.Timestamp);
            return v1;
        }
        else
        {
            Console.WriteLine("v2 " + v1.Timestamp);
            return v2;
        }       
    });
    result.Subscribe(x => Console.WriteLine(x));