193

RxJavamapでvsflatMapをいつ使用しますか?

たとえば、JSON を含むファイルを JSON を含む文字列にマップするとします。

を使用して、何とかmap対処する必要があります。Exceptionしかし、どのように?:

Observable.from(jsonFile).map(new Func1<File, String>() {
    @Override public String call(File file) {
        try {
            return new Gson().toJson(new FileReader(file), Object.class);
        } catch (FileNotFoundException e) {
            // So Exception. What to do ?
        }
        return null; // Not good :(
    }
});

を使用するflatMapと、はるかに冗長になりますが、問題を のチェーンに転送し、Observables別の場所を選択して再試行した場合にエラーを処理できます。

Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
    @Override public Observable<String> call(final File file) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override public void call(Subscriber<? super String> subscriber) {
                try {
                    String json = new Gson().toJson(new FileReader(file), Object.class);

                    subscriber.onNext(json);
                    subscriber.onCompleted();
                } catch (FileNotFoundException e) {
                    subscriber.onError(e);
                }
            }
        });
    }
});

のシンプルさが気に入っていますが、 (冗長さではなく)mapのエラー処理が気に入っています。flatmapこれに関するベストプラクティスは見たことがなく、実際にどのように使用されているのか興味があります.

4

11 に答える 11

127

mapあるイベントを別のイベントに変換します。 flatMap1 つのイベントを 0 個以上のイベントに変換します。(これはIntroToRxから取得したものです)

json をオブジェクトに変換したいので、 map を使用するだけで十分です。

FileNotFoundException の処理も別の問題です (map または flatmap を使用してもこの問題は解決しません)。

例外の問題を解決するには、チェックされていない例外をスローするだけです。RX は onError ハンドラを呼び出します。

Observable.from(jsonFile).map(new Func1<File, String>() {
    @Override public String call(File file) {
        try {
            return new Gson().toJson(new FileReader(file), Object.class);
        } catch (FileNotFoundException e) {
            // this exception is a part of rx-java
            throw OnErrorThrowable.addValueAsLastCause(e, file);
        }
    }
});

flatmap とまったく同じバージョン:

Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
    @Override public Observable<String> call(File file) {
        try {
            return Observable.just(new Gson().toJson(new FileReader(file), Object.class));
        } catch (FileNotFoundException e) {
            // this static method is a part of rx-java. It will return an exception which is associated to the value.
            throw OnErrorThrowable.addValueAsLastCause(e, file);
            // alternatively, you can return Obersable.empty(); instead of throwing exception
        }
    }
});

flatMap バージョンでは、単なるエラーである新しい Observable を返すこともできます。

Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
    @Override public Observable<String> call(File file) {
        try {
            return Observable.just(new Gson().toJson(new FileReader(file), Object.class));
        } catch (FileNotFoundException e) {
            return Observable.error(OnErrorThrowable.addValueAsLastCause(e, file));
        }
    }
});
于 2014-04-08T15:45:14.813 に答える
82

FlatMap は map と非常によく似た動作をします。違いは、適用される関数がオブザーバブル自体を返すことです。そのため、非同期操作のマッピングに完全に適しています。

実際的な意味では、 Map が適用する関数は、チェーンされた応答を変換するだけです (Observable を返しません)。FlatMap が適用される関数は を返しますがObservable<T>、そのため、メソッド内で非同期呼び出しを行う予定がある場合は FlatMap をお勧めします。

概要:

  • Map は型 T のオブジェクトを返します
  • FlatMap は Observable を返します。

明確な例は、http: //blog.couchbase.com/why-couchbase-chose-rxjava-new-java-sdkで確認できます。

Couchbase Java 2.X クライアントは、Rx を使用して便利な方法で非同期呼び出しを提供します。Rx を使用しているため、メソッド map と FlatMap があり、ドキュメントの説明は一般的な概念を理解するのに役立つ場合があります。

エラーを処理するには、サブスクライバーで onError をオーバーライドします。

Subscriber<String> mySubscriber = new Subscriber<String>() {
    @Override
    public void onNext(String s) { System.out.println(s); }

    @Override
    public void onCompleted() { }

    @Override
    public void onError(Throwable e) { }
};

このドキュメントを見ると役立つかもしれません: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

RX でエラーを管理する方法に関する適切なソースは、https ://gist.github.com/daschl/db9fcc9d2b932115b679 にあります。

于 2014-12-09T06:06:55.170 に答える
13

関数内で独自のカスタム ObservableをflatMap実際に使用する必要はなく、標準のファクトリ メソッド/演算子に依存できます。

Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
    @Override public Observable<String> call(final File file) {
        try {
            String json = new Gson().toJson(new FileReader(file), Object.class);
            return Observable.just(json);
        } catch (FileNotFoundException ex) {
            return Observable.<String>error(ex);
        }
    }
});

一般に、RxJava でできる限り多くのセーフガードを配置したとしても、可能であれば onXXX メソッドとコールバックから (ランタイム) 例外をスローすることは避ける必要があります。

于 2015-05-19T16:08:35.013 に答える
1

場合によっては、オブザーバブルが別のオブザーバブルを返す、一連のオブザーバブルが発生する可能性があります。「flatmap」の種類は、最初のオブザーバブルに埋め込まれている2番目のオブザーバブルをアンラップし、サブスクライブ中に2番目のオブザーバブルが吐き出すデータに直接アクセスできるようにします。

于 2017-08-19T16:31:24.697 に答える