为什么没有只接受错误处理程序的Subscribe重载

本文关键字:程序 处理 Subscribe 重载 错误 为什么 | 更新日期: 2023-09-27 17:59:42

IObservable有Next、Next+Error、Next+Complete、Next+Complete+Error的Subscribe重载,但为什么只有Errors没有可观察到的?

我认为这是因为可能存在异常的IOobservable,它会导致冲突,即:

IObservable<Exception> obs;
obs.Subscribe(ex => { });

RX不知道你是在订阅Next还是Error。

有没有一种方法可以在不创建空的Complete委托的情况下单独订阅错误?

obs.Subscribe(
    o => { },
    ex =>
    {
        // error-handling-code
    });

为什么没有只接受错误处理程序的Subscribe重载

好吧,这似乎是一个智力问题,所以:

从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=()=>{},底层基础设施也必须实现它。指定它不会失去任何性能。

从观察者模式的逻辑角度来看,您的意图是异步订阅元素/事件序列。省略OnNext函数而只保留OnError的方法签名会误导Rx库的用户。如果你明确表示你不想在OnNext上做任何事情,那就更清楚了。

一旦接收到OnCompleted或OnError方法,Rx语法保证订阅可以被视为完成

您要做的相当于使foreach循环为空并等待异常:

try
{
    foreach (var e in sequence)
    {
        // do nothing
    }
}
catch (Exception ex)
{
    // Do something
}

这不是常见的情况。

我认为这是您忽略的:

一旦接收到OnCompletedOnError方法语法保证订阅可以被视为已完成

  1. 如果您只关心将终止操作的异常尝试接球是你所需要的
  2. 如果您关心异常的顺序,则必须捕获它们并返回使用observer.OnNext(ex),不中断使用observer.OnError的订阅