小编典典

你什么时候在 RxJava 中使用 map 和 flatMap?

all

你什么时候在 RxJava* 中使用mapvs ?flatMap *

比如说,我们想将包含 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我还没有看到任何关于这个浮动的最佳实践,我很好奇它是如何在实践中使用的。


阅读 69

收藏
2022-07-14

共1个答案

小编典典

map将一个事件转换为另一个事件。
flatMap将一个事件转换为零个或多个事件。(这取自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));
        }
    }
});
2022-07-14