确定并操作 CombineLatest 中的最新更新序列
Determine and operate on the latest updated sequence in a CombineLatest
我想知道是否有一个现有的运算符或某种逻辑可以让我用 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
}
在这种情况下,left
和 right
将是输入序列,传递给该方法的 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
}
其中,不是使用布尔值来区分最近更新的序列,而是每个序列都有自己包含的函数形式的行为。
这种运算符的一个用例是我想要一个共享结果,该结果取决于 left
和 right
序列的某种组合(就像 CombineLatest
) , 但该优先权给予拥有最新信息的那个。我希望我的意图足够明确。
是否有现有的运算符具有类似的底层逻辑或可以适应此目的?否则我怎么能完成这样的行为呢?我对一些可能有用的运算符有一个模糊的想法,但似乎可能有很多不同的方法,我只是不确定要采用哪种最佳方法来实现我想要的。
您可以尝试将 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));
我会这样做:
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");
我想知道是否有一个现有的运算符或某种逻辑可以让我用 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
}
在这种情况下,left
和 right
将是输入序列,传递给该方法的 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
}
其中,不是使用布尔值来区分最近更新的序列,而是每个序列都有自己包含的函数形式的行为。
这种运算符的一个用例是我想要一个共享结果,该结果取决于 left
和 right
序列的某种组合(就像 CombineLatest
) , 但该优先权给予拥有最新信息的那个。我希望我的意图足够明确。
是否有现有的运算符具有类似的底层逻辑或可以适应此目的?否则我怎么能完成这样的行为呢?我对一些可能有用的运算符有一个模糊的想法,但似乎可能有很多不同的方法,我只是不确定要采用哪种最佳方法来实现我想要的。
您可以尝试将 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));
我会这样做:
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");