2017-05-23 12 views
1

次のコード例は、(Rx)Swiftの臭いがありますが、反応性機能とスロー機能を備えたすべての言語に共通の質問です。反応的なデザイン:スローとパブリッシュのエラー

観測可能なシーケンスを返す関数を考えてみましょう。ただし、シーケンスを作成する前にいくつかのサニティチェックを行います。チェック失敗は、シーケンスが値を生成できないことを意味します。

状態妥当性チェックに失敗した場合には
func yieldFoos() -> Observable<Foo> { 
    guard isValid(internalFoo) else { 
    // throw or return one shot observable? 
    } 
    return createValidObservable(from: internalFoo) 
} 

、関数throwや、これまで単にエラーが発生します観察可能なワンショットを、返す必要がありますか?

スローイングは論理的にきれいになります(これは障害が発生するのを防ぐためのものです)が、実行コードが違って実行ブロックが異なるため、異なる実行スコープの複数のエラー処理ポイントが発生します。

観察可能なワンショットは、より短くてきれいな呼び出しコードになりますが、何らかの形で間違っていると感じます。観察可能性は、簡潔さのために、非順次エラー状態のための搬送波であることが強制される。

次のような意見がありますか?見過ごされていた別の優雅なソリューションですか?あなたはそれを呼び出すとき、

func yieldFoos() -> Observable<Foo> { 
    Observable.create { observer in 

     guard isValid(internalFoo) else { 
      observer.onError(yourError) 
     } 

     let subscription = 
      createValidObservable(from: internalFoo) 
       .subscribe(onNext: { foo in 
        observer.onNext(foo) 
        observer.onCompleted() 
       }) 
     return Disposables.create { 
      // your dispose 
      subscription.dispose() 
     } 
    } 

} 

そして:

答えて

2

私はそれがエラーが発生することは観察可能なため間違っていることを、あなたの気持ちについてのだろうか。それは仕事の一部です。

考えてみるとcreateValidObservable(from:)関数は有効なinternalFooを渡してもエラーを出す可能性がありますので、yieldFoos()というコードは、とにかく出力エラーを処理できるように準備する必要があります。すべてのエラー処理コードをまとめてロールバックすることもできます。私はさらに進んで、作成関数がエラーを出してyieldFoos関数を削除することによって、無効なfoos自体を処理できるようにします。あなたがしたい場合は、投げたり前提条件によってエラーを処理する必要が

さて、yieldFoos()はその後、観測可能ではなくDriverを戻します(ドライバがエラーを出さないため。)

func yieldFoos() -> Observable<Foo> { 
    guard isValid(internalFoo) else { 
     return Observable.error(myError) 
    } 
    return createValidObservable(from: internalFoo) 
} 

私はObservableを持ってすぐにエラーを返すのは間違っているというあなたの気持ちを乗り越える必要があると思います。それはObservableが行うための完全に有効なものであり、Observableを使用するすべてのコードが処理する準備が必要です。

+0

Observableがエラーを出すのは間違いではありません。私は、そのようなエラーは最初に観測可能なものを作成するのではなく、「観測可能」(シーケンスを続けることができない)でなければならないと感じています。シーケンスの失敗は正常ですが、作成の失敗は例外的な不一致です。しかし、シングルショットObservable.error演算子の存在は、あまりにも多くのことを考えているかもしれないことを示唆しています。 –

+0

create関数が無効なinternalFooを渡した場合、シーケンスを続行することができなくなります。:-) Observableエラーをそれらのバージョンとして考えたり、非同期イベントのスローとして考えることができます。これは、処理されるまでパイプを介して伝播するというスローのように機能します。 –

+0

これは、このようにしていますか?リアクティブコードでは、一般的な投げ方の使用ケースは少なくなりますか?私は、主な反応概念の1つは、すべてが徐々に非同期で怠け者になる可能性があると考えていますが、変換コードは気にしないでください。スローが本質的に同期しているのに対して... –

1

あなたの機能は次のようなものでなければなりません

yieldFoos() 
    .subscribe(
    onNext: { foo in 
     // your code with foo 
    }, 
    onError: { error in 
     // manage errors 
    }) 
    .addDisposableTo(disposeBag) 
+1

私はオブザーバブルを構築し、使用する方法を知っています。ありがとうございます。私は例外的な失敗を投げたり、シーケンスに入れなければならないかどうかを尋ねています。あなたは、推論することなく、シーケンスを好むようです。 –

関連する問題