Reactive Extensions:缓冲区直到其他流完成

时间:2017-01-23 16:12:56

标签: .net system.reactive

我发出请求并等待响应流上的该请求的响应。等待时,更新流可能会有更新。

我想在响应流完成时获得这些更新。像这样:

Response (cold)   |      x y z |
Updates (hot)     | 1 2    3        4 |

Result            |      x y z 123  4 |

我似乎无法做到正确。是否有一些巧妙的运营商组合能够满足我的需求?

2 个答案:

答案 0 :(得分:2)

从问题图中:

缓冲所有更新,直到响应完成,然后显示其余的更新。 回复立即出现。

updates.TakeUntil(response.LastAsync())
       .ToArray()
       .SelectMany(x => x)
       .Concat(updates)
       .Merge(response);

答案 1 :(得分:1)

这会有效,但事实上你不能像单行一样困扰我:

var updatesReplayed = updates.Replay();
updatesReplayed.Connect();

var results = response.Concat(updatesReplayed);

此处的测试证明了功能性:

// time               | 1 2 3 4 5 6 7 8 9
// Response(cold)     |     x y z |
// Updates(hot)       | 1 2   3       4 |
// Result             |     x y z 123 4 |

var scheduler = new TestScheduler();
    var updates = scheduler.CreateHotObservable(
        ReactiveTest.OnNext(100.ToMsTicks(), "1"),
        ReactiveTest.OnNext(200.ToMsTicks(), "2"),
        ReactiveTest.OnNext(400.ToMsTicks(), "3"),
        ReactiveTest.OnNext(800.ToMsTicks(), "4"),
        ReactiveTest.OnCompleted<string>(900.ToMsTicks())
    );

    var response = scheduler.CreateColdObservable(
        ReactiveTest.OnNext(300.ToMsTicks(), "x"),
        ReactiveTest.OnNext(400.ToMsTicks(), "y"),
        ReactiveTest.OnNext(500.ToMsTicks(), "z"),
        ReactiveTest.OnCompleted<string>(600.ToMsTicks())
    );

    var expectedResults = scheduler.CreateHotObservable(
        ReactiveTest.OnNext(300.ToMsTicks(), "x"),
        ReactiveTest.OnNext(400.ToMsTicks(), "y"),
        ReactiveTest.OnNext(500.ToMsTicks(), "z"),
        ReactiveTest.OnNext(600.ToMsTicks(), "1"),
        ReactiveTest.OnNext(600.ToMsTicks(), "2"),
        ReactiveTest.OnNext(600.ToMsTicks(), "3"),
        ReactiveTest.OnNext(800.ToMsTicks(), "4"),
        ReactiveTest.OnCompleted<string>(900.ToMsTicks())
    );

    var replayed = updates.Replay();
    replayed.Connect();

    var results = response.Concat(replayed);
    var observer = scheduler.CreateObserver<string>();
    results.Subscribe(observer);

    scheduler.Start();
    ReactiveAssert.AreElementsEqual(expectedResults.Messages, observer.Messages);