Rx:Aggregate IObservable&lt; ...&gt;到IObservable <unit> </unit>

时间:2014-04-23 14:06:16

标签: system.reactive

我有一个IObservable<...>类型的observable,需要从函数返回一个IObservable<Unit>类型的observable。目前我这样做:

IObservable<Unit> DoSomething() {
    var observable = SomeOtherMethodThatReturnsObservable();

    // convert Convert IObservable<...> to IObservable<Unit>
    var ret = new AsyncSubject<Unit>();
    observable.Subscribe(_ => { }, ret.OnCompleted);
    return ret;
}

有更好的方法吗?也许扩展方法或其他什么?

1 个答案:

答案 0 :(得分:4)

我不会使用您在制作中提供的示例,因为它不考虑以下内容:

  • 如果Observable错误会怎样?
    • 错误被吃掉,消费者永远不知道观察结果已经结束。
  • 如果消费者处理它的订阅会怎样?
    • 基础订阅未被处理
  • 如果消费者从不订阅,会发生什么?
    • 基础观察者仍然订阅。

通常,使用内置运算符可提供最佳实现。

这是&#34; Rx-y&#34;这样做的方式。

source.IgnoreElements()
    .Cast<Unit>()
    .Concat(Observable.Return(Unit.Default));

这是另一种做同样事情的方法::)

没有内置运营商。这可以说更有效率,但这里没有真正的收获。

// .Cast<Unit>()
Observable.Create<Unit>(o => { // Also make sure you return the subscription!
    return source.Subscribe(
        // .IgnoreElements()
        _ => { },
        // Make sure errors get passed through!!!
        o.OnError,
        // .Concat(Observable.Return(Unit.Default));
        () => {
            o.OnNext(Unit.Default);
            o.OnCompleted();
        });
});

以下是如何只写一次。

public static class ObsEx
{
    public static IObservable<Unit> WhenDone<T>(this IObservable<T> source)
    {
        return Observable.Create<Unit>(observer =>
        {
            return source.Subscribe(
                _ => { },
                observer.OnError,
                () => {
                    observer.OnNext(Unit.Default);
                    observer.OnCompleted();
                });
        });
    }
}

并像这样使用它:source.WhenDone();