10

为什么 RX 有以下语法OnNext* (OnError|OnCompleted)?而不是(OnNext|OnError)* OnCompleted?从实现的角度来看,这很清楚(这也与IEnumerableand有共同的语义yield),但我想这与现实生活中的情况不同。在现实生活中 - 生产者生成混合的数据流和异常(并且异常不会破坏生产者)。

问题:如果我理解正确,唯一可能的解决方案是使可观察的返回复杂数据结构结合初始数据和产生的异常(Observable.Timestamp()并且.TimeInterval()具有类似的概念)或者还有其他选择吗?


目前我找到了以下解决方案:在可观察生产者内部,我手动处理异常并将它们传递给以下数据结构,这是我可观察的结果

public class ValueOrException<T>
{
    private readonly Exception ex;
    private readonly T value;

    public ValueOrException(T value, Exception ex)
    {
        this.value = value;
        this.ex = ex;
    }

    public ValueOrException(T value)
    {
        this.value = value;
    }

    public T Value
    {
        get { return this.value; }
    }

    public Exception Ex
    {
        get { return this.ex; }
    }
}
4

3 回答 3

7

如果消费者知道是否Exception是预期的,那么我说这里抛出异常是不正确的。

您本质上是在尝试传达状态或逻辑,而异常并不意味着这样做。异常意味着使系统(或至少是当前操作)陷入停顿,因为发生了一些代码本身并不知道如何从中恢复的事情。

在这种情况下,它恰好Exception是您的业务逻辑/状态的一部分,但这并不意味着您可以抛出它们。您需要将它们向下传递给您的消费者,然后让您的消费者处理它们。

ATuple<T, Exception>在这里可以工作,但是类型(以及属性)缺乏特异性通常很混乱,所以我建议创建一个专用类型来传达你的操作结果,并通过IObservable<T>.

于 2012-11-10T16:46:03.023 回答
1

OnError 表示发生不可恢复错误的消息,因此应重置流。恢复之后,下一个事件在异常之前发生的事件的上下文中没有意义。

例如,考虑事件流:

  • 用户加入了聊天
  • 用户加入了聊天
  • !!聊天崩溃,所以所有用户都被踢了
  • 用户加入了聊天

现在流消费者使用 Aggregate 函数来显示聊天的数量。最后应该显示什么?当然是1,不是3。我们应该在异常之后从头开始计数。

于 2014-01-24T15:03:15.897 回答
0

ValueOrException 看起来像函数式编程中的 Either 类型。您刚刚交换了左右。按照惯例,右代表成功,左代表失败。

于 2016-02-16T21:40:31.690 回答