1. ホーム
  2. java

[解決済み] RxJavaでmapとflatMapはいつ使うの?

2022-04-24 17:21:20

質問

どのような場合に mapflatMap RxJava ?

例えば、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 (冗長性ではなく)。この件に関するベストプラクティスを見たことがないので、実際にどのように使われているのか気になります。

どのように解決するのか?

map あるイベントを別のイベントに変換する。 flatMap 1つのイベントを0以上のイベントに変換します。(これは イントロToRx )

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));
        }
    }
});