web-dev-qa-db-ja.com

RxJava 2.x:FlowableまたはSingle / Completableを使用する必要がありますか?

Clean Architectureを使用してAndroidアプリを開発しています。RxJava2.xに移行しています。soapサービスにいくつかのネットワーク要求を作成する必要があるため、apiインターフェイスをドメインモジュール:

public interface SiginterApi {
    Observable<User> login(String user, String password);
    ...
    Observable<List<Campaign>> getCampaigns(List<Long> campaignIds);
}

ネットワーク要求は「Flowable」で行う必要があることを読みました。これは「コールドオブザーバブル」であるため、バックプレッシャー管理のためです。一方、リクエストの結果が成功(応答あり)またはエラーになることはわかっているので、FlowableまたはSingle、さらにはObservableを使用すべきかどうかはわかりません。

さらに、次のようなデータベースアクセスがあります。

public interface UserRepository extends Repository {
    Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
    ...
    Observable<User> findUser(String username, String hashedPassword);
}

CompletableメソッドでFlowable/Observable/saveUserを使用し、SingleメソッドでFlowable/Observable/findUserを使用する必要があるかどうかわかりません。

バックプレッシャーは、ソースObservableSubscriberが消費できるよりも速くアイテムを放出しているときに得られるものです。ほとんどの場合、ネットワーク要求などのcoldオブザーバブルではなく、hot observablesに懸念があります。

CompletableメソッドでObservable<Void>の代わりにsaveUserを使用し、リクエスト/レスポンスまたは入出力パターンに従うすべての場所でSingleを使用する必要があると思います。 Observableは、実際に連続したイベントストリームが必要な場合に使用する必要があります。

35
npace

Backpressure は、Observableがオペレーターまたはサブスクライバーが消費できるよりも速くアイテムを放出している場合に発生します

Observableは1つのアイテムのみを出力するため、Flowableは適切な候補ではないため、バックプレッシャーは問題ではありません。

したがって、本当の問題は、CompletableObservableを使用するか、saveUserSingleを使用するか、ObservablefindUserを使用するか、ここでは、APIを単純かつ明確にするために1つの結果(成功または失敗)のみが予想されるため、Completable/Singleを明確に使用する必要があります。 APIユーザーに誤解を与える可能性のある値が出力されます。

17
Nicolas Filotto

カーディナリティは、CompletableMaybeSingle

  • Maybe<T>は、カーディナリティが0または1のObservableです。つまり、存在するかどうかの結果を表します。
  • Single<T>は、常に結果、つまりカーディナリティ1を返すObservableです。
  • Completableは、Observable<Void>すなわち、0のカーディナリティ。

したがって、あなたの場合、この方法でリポジトリの署名を変更できます:

Completable saveUser(...);

Single<User> findUser(...);

backpressureFlowablesのようなObservablesについては言及しませんでした)。

8
lmarx

私が理解しているように、シングルを使用する必要があります:アイテムを取得することを確信している場合、そうでなければエラーが発生します。例:GET-card /:id

たぶん:あなたはアイテムを取得するかどうかわからない場合の正しいソリューションです。例:GET-card?license-plate = xvar3

完了可能:アクションが実行されたかどうかのみを知りたい場合。例:PUTまたはDETELE

観察可能:アイテムの量がそれほど多くない場合。

流動性:取得するアイテムの量がわからない場合。

2
dmarquina

うーん...

あなたはより複雑な状況に直面している一方で、質問は簡単なものではないと思います。

例えば。 ユーザーの保存(REST)>ユーザーの保存(SQLlite)

chain Rxストリームを1つにしたい場合があります。

だからあなたは宣言する

1。

Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);

そして、次のいくつかを使用します:flatMap, contactMap, switchMap

2。

...またはクラスの責任を混乱させないために、より望ましいかもしれないと思う(多くの場所で同じコードを使用するかもしれない)

Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);

RestService.saveUser(...)
.toFlowable() // Transform into Flowable 
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )

3。

ちなみに、Niceエラー処理が必要な場合に備えてCompletableを使用しないことをお勧めします。簡単にラップできますRetrofit.Response<Body> in SingleまたはFlowableでサーバーからのコード応答を利用します

0
murt