RxJava操作符的一些记录

来源:互联网 发布:@otree.cn 橙树网络 编辑:程序博客网 时间:2024/05/16 18:50

介绍

在项目中使用RxJava实现响应式编码有一段时间,RxJava的强大,简单的使用已经能够满足普通的开发需求,为了记录和加深自己的对RxJava的理解,写这篇博客记录一些自己对RxJava的使用和理解。

前期说明

下文用代码说明一些操作符的功能和使用。
首先提供基本的可观察对象,以下是基本的对象,后文中会根据需要进行修改。为了简化代码使用lamdba表达式。

static Observable<String> sampleObserbableString(){        return Observable.create(subscriber -> {            for (int i = 0; i < 2; i++) {                subscriber.onNext("start "+ i);                Logger.d("start "+ i);            }             subscriber.onCompleted();        });    }

Map

代码:先访问得到可观察的序列然后map转换,给每个值加上“map”,打印结果。

 sampleObservableString()                .map(new Func1<String, String>() {                    @Override                    public String call(String s) {                        return s+" map";                    }                })                .subscribe(new Subscriber<String>() {                    @Override                    public void onCompleted() {                        Logger.d();                    }                    @Override                    public void onError(Throwable e) {                        Logger.d(e.toString());                    }                    @Override                    public void onNext(String s) {                        Logger.d(s);                    }                });

可以看到,原来发射序列的onNext方法发送的值被map加工,然后观察得到被map加工后的结果。

Log打印
04-20 14:48:21.835 [RxAndroidFragment:onNext:121]: start 0 map
04-20 14:48:21.836 [RxAndroidFragment:lambdasampleObservableString1:130]: start 0
04-20 14:48:21.836 [RxAndroidFragment:onNext:121]: start 1 map
04-20 14:48:21.837 [RxAndroidFragment:lambdasampleObservableString1:130]: start 1
04-20 14:48:21.839 [RxAndroidFragment:onCompleted:111]:

官方说明:
map说明图

map:是对每个元素进行转换。

flatMap

代码:订阅打印方式和map的代码一样,只修改调用了flatmap方法

   sampleObservableString()                .flatMap(s -> sampleObservableString2())                .subscribe(打印结果)

可以看到,得到2*2=4次onNext打印结果。因为每次原始数据的onNext都激发了flatmap中新数据源发射数据。这里考虑有可能我两个observable都是String类型对结果的影响,我改变代码中的sampleObservableInteger2发射int包装类,并订阅。结果一样也是4次打印结果。

04-20 15:02:28.727 [RxAndroidFragment:onNext:116]: from 0
04-20 15:02:28.727 [RxAndroidFragment:lambdasampleObservableString23:135]: from 0
04-20 15:02:28.728 [RxAndroidFragment:onNext:116]: from 1
04-20 15:02:28.728 [RxAndroidFragment:lambdasampleObservableString23:135]: from 1
04-20 15:02:28.729 [RxAndroidFragment:lambdasampleObservableString2:125]: start 0
04-20 15:02:28.730 [RxAndroidFragment:onNext:116]: from 0
04-20 15:02:28.730 [RxAndroidFragment:lambdasampleObservableString23:135]: from 0
04-20 15:02:28.731 [RxAndroidFragment:onNext:116]: from 1
04-20 15:02:28.731 [RxAndroidFragment:lambdasampleObservableString23:135]: from 1
04-20 15:02:28.732 [RxAndroidFragment:lambdasampleObservableString2:125]: start 1
04-20 15:02:28.733 [RxAndroidFragment:onCompleted:106]:

官方说明:
flatmap说明图

flatmap:提供一种铺平序列的方式,然后合并这些Observables发射的数据,最后将合并后的结果作为最终的Observable。

借用这篇博客的说明:
flatMap() 的原理是这样的:
1. 使用传入的事件对象创建一个 Observable 对象;2. 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;3. 每一个创建出来的 Observable 发送的事件,都被汇入同一个 Observable ,而这个 Observable 负责将这些事件统一交给 Subscriber 的回调方法。这三个步骤,把事件拆成了两级,通过一组新创建的 Observable 将初始的对象『铺平』之后通过统一路径分发了下去。而这个『铺平』就是 flatMap() 所谓的 flat。

ConcatMap/FlatMapIterable

concatMap():函数解决了flatMap()的交叉问题(上图能看到flatmap有交叉情况)提供了一种能够把发射的值连续在一起的铺平函数,而不是合并它们。由于代码模拟比较简单就不说用代码说明。主要就是顺序有了保证。
flatMapInterable():和flatMap()很像。仅有的本质不同是,它不是原始数据项和生成的Observables,而是将源数据两两结成对并生成Iterable。

debounce

debounce是过滤掉由Observable发射的速率过快的数据,这就需要修改我的发射源。
代码如下:在发射3个元素的中间元素1时,休眠200毫秒,设置一个100毫秒间隔的debounce过滤

 static Observable<String> sampleObservableString() {        return Observable.create(subscriber -> {            for (int i = 0; i < 3; i++) {                if (i==1) {                    try {                        Thread.sleep(200);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                subscriber.onNext("start " + i);                Logger.d("start " + i);            }            subscriber.onCompleted();        });    }
 sampleObservableString()                .debounce(100, TimeUnit.MILLISECONDS)                .subscribe(打印结果)

打印结果:得到了2次结果,中间那次被过滤掉了。因为后两次间隔太近。

04-20 16:09:59.817 [RxAndroidFragment:lambdasampleObservableString1:150]: start 0
04-20 16:09:59.916 20468-20524/com.demo.liyi.HttpDemo D/mDemo: [RxAndroidFragment:onNext:134]: start 0
04-20 16:10:01.818 [RxAndroidFragment:lambdasampleObservableString1:150]: start 1
04-20 16:10:01.819 [RxAndroidFragment:lambdasampleObservableString1:150]: start 2
04-20 16:10:01.819 [RxAndroidFragment:onNext:134]: start 2
04-20 16:10:01.820 [RxAndroidFragment:onCompleted:124]:
图片说明:图片可以更好的说明
结果的图片说明

0 0
原创粉丝点击