首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在RxJava中,什么时候使用map和flatMap?

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

Stack Overflow用户
提问于 2014-04-04 03:26:03
回答 11查看 121.6K关注 0票数 192

什么时候在RxJava中使用mapflatMap

例如,我们希望将包含JSON的文件映射到包含JSON的字符串--

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

代码语言:javascript
复制
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链向下转发问题并处理错误:

代码语言:javascript
复制
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的错误处理(而不是冗长)。我还没有看到任何关于这方面的最佳实践,我很好奇这是如何在实践中使用的。

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2014-04-08 23:45:15

map将一个事件转换为另一个事件。flatMap将一个事件转换为零个或多个事件。(摘自IntroToRx)

当你想把你的json转换成一个对象时,使用map就足够了。

处理FileNotFoundException是另一个问题(使用map或flatmap不能解决这个问题)。

要解决您的异常问题,只需使用未检查的异常抛出它: RX将为您调用onError处理程序。

代码语言:javascript
复制
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的版本完全相同:

代码语言:javascript
复制
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版本中,它只是一个错误。

代码语言:javascript
复制
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));
        }
    }
});
票数 127
EN

Stack Overflow用户

发布于 2014-12-09 14:06:55

FlatMap的行为与map非常相似,不同之处在于它所应用的函数本身返回一个可观察对象,因此它非常适合在异步操作上进行映射。

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

摘要:

  • 映射返回T类型的对象
  • FlatMap返回可观察对象。

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

Couchbase Java2.x客户端使用Rx以一种方便的方式提供异步调用。因为它使用Rx,所以它有方法map和FlatMap,它们的文档中的解释可能有助于理解一般概念。

要处理错误,请重写您的susbcriber上的onError。

代码语言:javascript
复制
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上找到

票数 81
EN

Stack Overflow用户

发布于 2015-05-19 05:59:56

在本例中,您需要map,因为只有一个输入和一个输出。

map提供的函数只接受一个项目,并返回一个项目,该项目将进一步(只有一次)向下发出。

flatMap提供的函数接受一个项目,然后返回一个"Observable",这意味着新的"Observable“的每一项都将被单独发送。

也许代码会帮你把事情弄清楚:

代码语言:javascript
复制
Observable.just("item1").map( str -> {
    System.out.println("inside the map " + str);
    return str;
}).subscribe(System.out::println);

Observable.just("item2").flatMap( str -> {
    System.out.println("inside the flatMap " + str);
    return Observable.just(str + "+", str + "++" , str + "+++");
}).subscribe(System.out::println);

输出:

代码语言:javascript
复制
inside the map item1
item1
inside the flatMap item2
item2+
item2++
item2+++
票数 66
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22847105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档