操作符总览

Rxjava为函数式编程提供了众多的操作符,操作符的运用可以使得程序逻辑更为简洁。

网上已有众多操作符说明教学,但不亲身总结和尝试一遍,是难以体会到其中奥妙与融会贯通的,简单记录总结以备大家使用参考。

创建操作符

just

自动依次发送事件序列。
实例:
Observable .just("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")
依次发送调用onNext(),最后默认调用complete()

create

手动创建事件序列,返回一个可自由操作的emitter,优点是自由控制事件流程。
emitter.onNext();
emitter.onError();
emitter.onComplete();

fromIterable

传入数组并按角标依次发送事件。
Observable.fromIterable(list),每次接收单个元素。

fromArray

传入数组一次性发送,一次接收所有元素。

timer

延时发送事件 Observable .timer(2, TimeUnit.SECONDS)

interval

可取代CountDownTimer、Handler,5秒发送一次事件:
Observable .interval(5, TimeUnit.SECONDS)

实例:取代handler进行定时计划

private Disposable mDisposable;@Overrideprotected void doSomething() {mDisposable = Flowable.interval(20, TimeUnit.SECONDS).doOnNext(new Consumer<Long>() {@Overridepublic void accept(@NonNull Long aLong) throws Exception {doTask();}});}/*** 销毁时停止计划*/@Overrideprotected void onDestroy() {super.onDestroy();if (mDisposable != null){mDisposable.dispose();}}
intervalRange

给事件更多的时间控制:
intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit)
参数1:起始发送值
参数2:发送数量
参数3:首次发送延迟事件
参数4:每次发送事件间隔
参数5:时间单位

Range

依次发送范围内的事件
Observable.range(2, 6),接收类型Integer

转换操作符

map

实现单个数据的转换

实例:把网络中ResponseBody用Gson转换为相对应的数据实体再下发给子类。

  .map(new Function<Response, Number>() {@Overridepublic MobileAddress apply(@NonNull Response response) throws Exception {if (response.isSuccessful()) {ResponseBody body = response.body();if (body != null) {Log.e(TAG, "map:转换前:" + response.body());return new Gson().fromJson(body.string(), MobileAddress.class);}}return null;}}).observeOn(AndroidSchedulers.mainThread()).doOnNext(new Consumer<MobileAddress>() {@Overridepublic void accept(@NonNull MobileAddress s) throws Exception {Log.e(TAG, "doOnNext: Number:" + s.getNumbser() + "\n");}})
flatMap和concatMap

两者都可以实现数据集合中一对多事件的转换,后者会按发送的顺序获取接收结果,前者可能是乱序接收(不确定哪个事件先完成)。

一对多事件转换:在flatMap集合中例如可以操作一个公司实体,并转换为单个部门实体,返回后在后续的accept中,又可以使用单个部门实体对每个成员进行逻辑处理。

实例:

Observable.fromArray(1,2,3,4,5).flatMap(new Function<Integer, ObservableSource<Integer>>() {@Overridepublic ObservableSource<Integer> apply(@NonNull Integer integer) throws Exception {int delay = 0;if(integer == 3){delay = 500;//延迟500ms}return Observable.just(integer *10).delay(delay, TimeUnit.MILLISECONDS);}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {@Overridepublic void accept(@NonNull Integer integer) throws Exception {Log.e("tag","accept:"+integer);}});

使用flatMap结果:10,20,40,30,50
使用contactMap结果:10,20,30,40,50

buffer

分批发送事件

实例:
Observable .just(1, 2, 3, 4, 5, 6) .buffer(2)
发送1,2;发送3,4;在发送5,6

合并操作符

merge和contat

两者都可以合并多个Observable事件,前者发送顺序不确定(并行无序),后者按顺序发送(串行有序)。
mergeArray和concatArray效果相同,适用于大于4个事件的情况。

实例:
定义cache和network两个事件,先查看缓存是否有数据,有即onNext去刷新页面,没有则onComplete读取网络数据。

 Observable.concat(cache,network)
concatDelayError和 mergeDelayError

两者都可以在merge和contat操作中出现错误时停止发送当前事件集合,但不影响合并中的另一个事件集合发送

zip

zip 操作符可以将多个 Observable 的数据结合为一个数据源再发射出去

实例:分别请求生日、地址、性别等信息后,将多个请求结果合成一个,再进行UI更新。

....分别请求生日、地址...
Observable.zip(observable1, observable2, new BiFunction<Birth, Address, String>() {@Overridepublic String apply(@NonNull Birth birth, @NonNull Address address) throws Exception {return "合并后的数据为 Birth:"+birth.getResult()+" Address:"+address.getResult();}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {@Overridepublic void accept(@NonNull String s) throws Exception {Log.e(TAG, "accept: 成功:" + s+"\n");}});
过滤操作符
操作符 说明
filter 自定义筛选条件,返回boolean
distinct 去重
distinctUntilChanged 过滤连续相同事件
skip,skipLast 跳过前n个事件或最后n个
take和takeLast 只接收前n个事件或最后n个
elementAt和elementAtOrError 前者只发送第n个,可设置默认值,不抛异常;后者越界抛异常。
ignoreElements 只接收完成和报错信息
distinct 去重
ofType 指定接收数据类型
throttleFirst/throttleLast 只接收指定时间内第一个或最后一个事件

其他操作符

do

doOnEach() :当Observable每发送一次事件就会调用一次(包含onNext(),onError(),onComplete())
doOnNext(): 执行 onNext()前调用
doAfterNext(): 执行onNext()后调用
doOnComplete():执行onComplete()前调用
doOnError():执行 onError()前调用
doOnTerminate(): 执行终止(无论正常发送完毕/异常终止)
doFinally(): 最后执行
doOnSubscribe() :观察者订阅是调用
doOnUnScbscribe(): 观察者取消订阅时调用

onErrorReturn

捕获错误并返回,不发送后续事件。

onExceptionResumeNext/onErrorResumeNext

捕获错误跳过当前事件同时不中断发送后续事件。

retry

retry() : 出现错误时,让被观察者重新发送数据。若错误一直发生,则一直重新发送
retry(long time):与retry不同的书,若错误一直发生,被观察者则一直重新发送数据,但这持续重新发送有次数限制
retry(Predicate predicate) : 出现错误时,根据指定逻辑(可以捕获到发生的错误)决定是否让被观察者重新发送数据
retry(new BiPredicate<Integer, Throwable>):出现错误时,根据指定逻辑(可以捕获重发的次数和发生的错误)决定是否让被观察者重新发送数据
retry(long time,Predicate predicate) : 出现错误时,根据指定逻辑(可以捕获到发生的错误)决定是否让被观察者重新发送数据。并且有持续重发的次数限制

retryUntil

遇到错误时根据制定规则选择是否重发

retryWhen

遇到错误时,将发生的错误传递给一个新的被观察者(Observable),并决定是否需要重新订阅原始被观察者(Observable)

repeat和repeatWhen

repeat重复发射 observable的数据序列,可以使无限次也可以是指定次数.不传时为重复无限次。
repeatWhen遇到错误选择返回object给新观察者或中止事件

返回参数选择:
Observable.empty();
发送Complete事件,但不会回调观察者的Complete()

onComplete()
直接完成。

Observable.error(new Throwable("不再重新订阅事件"));

Observable.just(1);
继续发送事件。

debounce

一定的时间内没有操作就会发送事件(只会发送最后一次操作的事件)

实例:
Observable.intervalRange(1, 2, 3, 4, TimeUnit.SECONDS)
.debounce(2, TimeUnit.SECONDS)
只有最后一个4的事件会被发送(2秒后)

条件操作符

操作符 说明
all 判断被观察者所有事件是否满足某个事件,如果全部满足则返回true,都在返回false
takeUntil 当事件满足设定的条件时,该事件的下一个事件不会被发送了。包含超过临界条件的第一个事件
takeWhile 当事件满足设定的条件时,发送事件
skipUntil 直到设定的条件事件发出之后,开始发送原始事件。
skipWhile 跳过while范围内事件
amb 多个Observable序列中,只发送第一个
contains 是否存在特定元素
exists 是否满足特定条件
DefaultIfEmpty 如果没有正常结束事件(onComlete执行),返回默认值
SequenceEqual 判断两个事件序列是否是相同的数据,相同的顺序,相同的终止状态

相似操作符对比

timer():用于创建Observable,延迟发送一次。
interval():用于创建Observable,跟TimerTask类似,用于周期性发送。
delay():用于事件流中,可以延迟发送事件流中的某一次发送。

转载于:https://blog.51cto.com/13952501/2338316

RxJava2.x 萌新之路 操作符篇相关推荐

  1. OpenCV4萌新之路——详解图像读取函数 “imread”

    OpenCV4萌新之路--详解图像读取函数 "imread" 一.函数简析 二.参数详解 1.String& filename 2.flags = IMREAD_COLOR ...

  2. Java萌新入门的第一篇文章

    这篇文章是为了刚入门或者打算入门的萌新们写的,希望看完后能对Java有个初步认识.以后会不定时更新有关Java的干货,就这些要说的,以上. 先介绍下相关背景,不要觉得枯燥,了解一下很有必要. a.计算 ...

  3. ugui unity 取消选择_Unity暑期萌新入门:环境篇

    大家好,新一期又跟大家见面了. 上一节我们完成了角色的移动控制,然而John只能在空白的场景中移动.因此接下来这一节我们将添加关卡.调节光照,让John来到阴森的鬼屋.然后设置NavMesh(导航网格 ...

  4. unity 敌人自动攻击和寻路_Unity暑期萌新入门:环境篇

    大家好,新一期又跟大家见面了. 上一节我们完成了角色的移动控制,然而John只能在空白的场景中移动.因此接下来这一节我们将添加关卡.调节光照,让John来到阴森的鬼屋.然后设置NavMesh(导航网格 ...

  5. 游戏策划萌新之路(2)--游戏界的抄袭与借鉴

    抄袭,是中国游戏界绕不开的话题,游戏机制和玩法抄袭成本之低.法律追究之难以及国内知识产权保护力度不足成为助长这一风气的主要问题. 入行第四天,策划组例会. 此时的我正在进行一个关于模拟经营类游戏的玩法 ...

  6. FL的萌新之路,开始了!

    作为小白的我终于准备上路了,先看下第一部分(/滑稽). 博客园不支持插入html插件,点我预览文件>> 没错就是sans的番茄酱! 以后还得更努力的学习啊! 转载于:https://www ...

  7. 声卡loopback有什么用_萌新做音乐那点事 | 外置专业声卡的选择方法与推荐

    [本文长期更新,感兴趣可以点收藏] 前言:作为一名独立音乐人,接触了这么多年,自认为了解一点声卡的常识,为正在准备购买声卡[或是音频接口]的萌新音乐人做一篇介绍文. 市面常见的声卡品牌 常见的品牌真的 ...

  8. 萌新爬虫系列01——爬取模型网站作品

    这是萌新的第一个爬虫,也是萌新发布的第一篇文章. 首先声明一下本萌新在过去一个月内短程突击学习了Python网络爬虫,在此提前一并对倾囊相授,传道授业解惑的各位大神大佬们表示真挚的感谢和崇高的敬意!! ...

  9. 从萌新玩家到游戏开发,IEG首位女专家的升级之路

    我们为什么叫「递归」 "递归" (recursion) 是一种在程序设计语言中被广泛使用的算法.它有两大特点,一是调用自己,二是化繁为简.我们当中那些优秀的技术人又何尝不是如此?他 ...

最新文章

  1. 镜头评价指标及测试方法(三)--------测量原理及3D相机调查
  2. 怎样用c语言写高速超速罚款标准,pta高速公路超速处罚(C语言)
  3. java 做登录跳转404_springboot 访问路径错误跳转到404(实现方法一)
  4. tomcat 和 jdk 版本 对应关系
  5. 单面煎鸡蛋,健康有风险
  6. 动态规划-装配线调度
  7. Oracle 启动例程 STARTUP参数说明
  8. Web服务器的配置与管理(2) 虚拟主机技术
  9. C语言 | 读写文件
  10. java se程序设计_JavaSE--Java 的基本程序设计结构
  11. dell笔记本插上耳机没有声音_跑男的耳机没有声音,沙溢只用一句话诈出来,不愧是《王牌》常客...
  12. 测试一下live writer
  13. SpringBoot实战(十三):Spring Boot Admin 动态修改日志级别
  14. Python实现代码行数统计工具
  15. JAVA中遗留的问题_java中遗留的小问题
  16. 苹果macfcpx视频剪辑软件:Final Cut Pro X
  17. js数组指定位置添加元素_34. 在排序数组中查找元素的第一个和最后一个位置(难度:中等)
  18. 关于navicat设置主键属性identity
  19. 经典谢幕千千静听(最终版本)7.0.4 去广告增强版下载
  20. php chr 1,PHP chr()用法及代码示例

热门文章

  1. 【翻译】Ext JS最新技巧——2014-8-13
  2. Confluence 6 系统运行信息中的 JVM 内存使用情况
  3. RESTful再理解
  4. thinkphp 使用外部php或html 原理
  5. 10 个强大的 Apache 模块
  6. SGU 224.Little Queens
  7. 40条优化php代码的小实例
  8. UPDATE 时主键冲突引发的思考
  9. 代码体积减少80%!Taro H5转换与优化升级
  10. 苹果手机怎么投屏 如何操作