10

なぜ RX は次の文法を持っているのOnNext* (OnError|OnCompleted)ですか? 代わりに(OnNext|OnError)* OnCompleted?これは、実装の観点からは非常に明確です (これは および と共通のセマンティクスを持っていますIEnumerable)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と言います。

基本的に、例外が意図していない状態またはロジックを伝えようとしています。例外は、コードが本質的に回復方法を知らない何かが発生したため、システム (または少なくとも現在の操作) を停止させることを目的としています。

この場合、 anExceptionはたまたまビジネス ロジック/状態の一部ですが、それはそれらをスローできるという意味ではありません。それらをダウンストリームでコンシューマに渡し、コンシューマに処理させる必要があります。

ATuple<T, Exception>はここでピンチで機能しますが、型 (およびプロパティ) に関する特異性の欠如は通常厄介です。そのため、専用の型を作成して操作の結果を伝え、 を介して公開することをお勧めしますIObservable<T>

于 2012-11-10T16:46:03.023 に答える
1

OnError は、回復不能なエラーが発生したため、ストリームをリセットする必要があるというメッセージを意味します。回復後、次のイベントは、例外の前に発生したイベントのコンテキストでは意味がありません。

たとえば、イベントのストリームを考えてみましょう:

  • ユーザーがチャットに参加しました
  • ユーザーがチャットに参加しました
  • !! チャットがクラッシュしたため、すべてのユーザーがキックされました
  • ユーザーがチャットに参加しました

ここで、ストリーム コンシューマーは Aggregate 関数を使用してチャットの数を表示します。最後に何を表示する必要がありますか?もちろん、3 ではなく 1 です。例外の後、ゼロからカウントを開始する必要があります。

于 2014-01-24T15:03:15.897 に答える
0

ValueOrException は、関数型プログラミングのいずれかの型のように見えます。左と右を入れ替えました。慣例により、Right は成功に使用され、Left は失敗に使用されます。

于 2016-02-16T21:40:31.690 に答える