IObservable的订阅重载次数为Next,Next + Error,Next + Complete,Next + Complete + Error,但为什么单独的错误没有可观察到的?
我认为这是因为可能存在异常的IObservable并且会引起冲突,即:
IObservable<Exception> obs;
obs.Subscribe(ex => { });
RX不知道你是订阅了Next还是Error。
有没有办法单独订阅错误而不创建一个空的完整代表?
obs.Subscribe(
o => { },
ex =>
{
// error-handling-code
});
答案 0 :(得分:6)
好的,这似乎是一个智力问题,所以:
从c#编译器的角度来看,对于IObservable方法签名,你提出的是(考虑到T = Exception):
public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext);
public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onError);
两种方法重载都具有相同的签名,编译器不支持它。
从接口角度来看,IObserver定义如下:
public interface IObserver<in T>
{
void OnCompleted();
void OnError(Exception error);
void OnNext(T value);
}
接口的实现者必须是这样的:
public class Observer<T> : IObserver<T>
{
public void OnCompleted()
{
}
public void OnError(Exception error)
{
// Do something with exception
}
public void OnNext(T value)
{
}
}
所以,即使你没有指定OnNext =()=&gt; {},底层基础设施必须实现它。你不会失去指定它的任何表现。
从观察者模式的逻辑角度来看,您的意图是异步订阅元素/事件序列。省略OnNext函数并仅保留OnError的方法签名会对Rx库的用户产生误导。如果你明确表明你不想做任何OnNext的事情,那就更清楚了。
收到OnCompleted或OnError方法后,Rx 语法保证可以认为订阅 结束。强>
您尝试做的事情相当于制作空的foreach循环并等待异常:
try
{
foreach (var e in sequence)
{
// do nothing
}
}
catch (Exception ex)
{
// Do something
}
这不常见。
答案 1 :(得分:1)
我认为这是你忽略的:
收到
OnCompleted
或OnError
方法后,Rx 语法保证订阅可以被认为是 完成强>
observer.OnNext(ex)
返回,而不是使用observer.OnError
中断订阅。