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

2022-08-31 06:25:12

你什么时候在RxJava中使用vs?mapflatMap

例如,假设我们要将包含 JSON 的文件映射到包含 JSON 的字符串中 -

使用 ,我们必须以某种方式处理。但是如何做到呢?mapException

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

使用 ,它要详细得多,但是如果我们选择其他地方甚至重试,我们可以将问题向下转发并处理错误:flatMapObservables

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

我喜欢 的简单性,但错误处理(而不是冗长)。我还没有看到任何关于这个浮动的最佳实践,我很好奇这在实践中是如何使用的。mapflatmap


答案 1

map将一个事件转换为另一个事件。 将一个事件转换为零个或多个事件。(这取自IntroToRxflatMap)

由于您希望将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);
        }
    }
});

与平面图完全相同的版本:

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

答案 2

FlatMap的行为非常像map,不同之处在于它应用的函数返回可观察性本身,因此它非常适合通过异步操作进行映射。

在实际意义上,Map应用的函数只是在链式响应上进行转换(不返回可观察量);而函数 FlatMap apply 返回一个 ,这就是为什么如果您计划在方法内部进行异步调用,则建议使用 FlatMap 的原因。Observable<T>

总结:

  • 映射返回类型 T 的对象
  • FlatMap 返回一个 Observable。

在这里可以看到一个明显的例子:http://blog.couchbase.com/why-couchbase-chose-rxjava-new-java-sdk

Couchbase Java 2.X Client使用Rx以方便的方式提供异步调用。由于它使用Rx,它具有方法映射和FlatMap,因此其文档中的解释可能有助于理解一般概念。

要处理错误,请在 susbcriber 上覆盖 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


推荐