将最新值与先前值组合在一个可观察流中

me-*_*e-- 4 .net c# reactive-programming system.reactive

我正在试图弄清楚如何采用可观察的序列T并获得T我的订阅者中最近和以前的值.这是我的秒杀代码:

static void Main(string[] args)
{
    var latest = new Subject<string>();
    var previous = latest.SkipLast(1);
    var latestWithPrevious = latest.CombineLatest(previous, (l, p) => new { Latest = l, Previous = p });

    latestWithPrevious.Subscribe(x => Console.WriteLine("Latest: {0} Previous: {1}", x.Latest, x.Previous));

    latest.OnNext("1");
    latest.OnNext("2");
    latest.OnNext("3");

    Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

我想要以下输出:

Publishing 1
Publishing 2
Latest: 2 Previous: 1
Publishing 3
Latest: 3 Previous: 2
Run Code Online (Sandbox Code Playgroud)

但是,我得到以下内容:

Publishing 1
Publishing 2
Latest: 2 Previous: 1
Publishing 3
Latest: 3 Previous: 1
Latest: 3 Previous: 2
Run Code Online (Sandbox Code Playgroud)

因此,"3"的发布将latest触发两个刻度latestWithPrevious:第一个具有旧值Previous,第二个具有正确的值Previous.

我怎样才能在这里实现我的目标?

Bra*_*don 8

使用Skip(1),而不是SkipLast(1). SkipLast跳过流中的最后N个条目.

此外,CombineLatest当它发生变化时,每个侧面仍会触发,因此您将获得比您想要的更多的事件.用Zip而不是CombineLatest. Zip只有在每一方产生下一个值后触发.

最后,颠倒语义. latest是跳过第一个值previous的系列,是包含第一个值的系列.

var source = new Subject<string>();
var previous = source;
var latest = source.Skip(1);
var latestWithPrevious = latest.Zip(previous, (l, p) => new { Latest = l, Previous = p});
Run Code Online (Sandbox Code Playgroud)