操作符分类
ReactiveX的每种编程语言的实现都实现了一组操作符的集合。不同的实现之间有很多重叠的部分,也有一些操作符只存在特定的实现中。每种实现都倾向于用那种编程语言中他们熟悉的上下文中相似的方法给这些操作符命名。
本文首先会给出ReactiveX的核心操作符列表和对应的文档链接,后面还有一个决策树用于帮助你根据具体的场景选择合适的操作符。最后有一个语言特定实现的按字母排序的操作符列表。
如果你想实现你自己的操作符,可以参考这里:实现自定义操作符
创建操作
用于创建Observable的操作符
Create
— 通过调用观察者的方法从头创建一个ObservableDefer
— 在观察者订阅之前不创建这个Observable,为每一个观察者创建一个新的ObservableEmpty/Never/Throw
— 创建行为受限的特殊ObservableFrom
— 将其它的对象或数据结构转换为ObservableInterval
— 创建一个定时发射整数序列的ObservableJust
— 将对象或者对象集合转换为一个会发射这些对象的ObservableRange
— 创建发射指定范围的整数序列的ObservableRepeat
— 创建重复发射特定的数据或数据序列的ObservableStart
— 创建发射一个函数的返回值的ObservableTimer
— 创建在一个指定的延迟之后发射单个数据的Observable
变换操作
这些操作符可用于对Observable发射的数据进行变换,详细解释可以看每个操作符的文档
Buffer
— 缓存,可以简单的理解为缓存,它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个FlatMap
— 扁平映射,将Observable发射的数据变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable,可以认为是一个将嵌套的数据结构展开的过程。GroupBy
— 分组,将原来的Observable分拆为Observable集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据Map
— 映射,通过对序列的每一项都应用一个函数变换Observable发射的数据,实质是对序列中的每一项执行一个函数,函数的参数就是这个数据项Scan
— 扫描,对Observable发射的每一项数据应用一个函数,然后按顺序依次发射这些值Window
— 窗口,定期将来自Observable的数据分拆成一些Observable窗口,然后发射这些窗口,而不是每次发射一项。类似于Buffer,但Buffer发射的是数据,Window发射的是Observable,每一个Observable发射原始Observable的数据的一个子集
过滤操作
这些操作符用于从Observable发射的数据中进行选择
Debounce
— 只有在空闲了一段时间后才发射数据,通俗的说,就是如果一段时间没有操作,就执行一次操作Distinct
— 去重,过滤掉重复数据项ElementAt
— 取值,取特定位置的数据项Filter
— 过滤,过滤掉没有通过谓词测试的数据项,只发射通过测试的First
— 首项,只发射满足条件的第一条数据IgnoreElements
— 忽略所有的数据,只保留终止通知(onError或onCompleted)Last
— 末项,只发射最后一条数据Sample
— 取样,定期发射最新的数据,等于是数据抽样,有的实现里叫ThrottleFirstSkip
— 跳过前面的若干项数据SkipLast
— 跳过后面的若干项数据Take
— 只保留前面的若干项数据TakeLast
— 只保留后面的若干项数据
组合操作
组合操作符用于将多个Observable组合成一个单一的Observable
And/Then/When
— 通过模式(And条件)和计划(Then次序)组合两个或多个Observable发射的数据集CombineLatest
— 当两个Observables中的任何一个发射了一个数据时,通过一个指定的函数组合每个Observable发射的最新数据(一共两个数据),然后发射这个函数的结果Join
— 无论何时,如果一个Observable发射了一个数据项,只要在另一个Observable发射的数据项定义的时间窗口内,就将两个Observable发射的数据合并发射Merge
— 将两个Observable发射的数据组合并成一个StartWith
— 在发射原来的Observable的数据序列之前,先发射一个指定的数据序列或数据项Switch
— 将一个发射Observable序列的Observable转换为这样一个Observable:它逐个发射那些Observable最近发射的数据Zip
— 打包,使用一个指定的函数将多个Observable发射的数据组合在一起,然后将这个函数的结果作为单项数据发射
错误处理
这些操作符用于从错误通知中恢复
辅助操作
一组用于处理Observable的操作符
Delay
— 延迟一段时间发射结果数据Do
— 注册一个动作占用一些Observable的生命周期事件,相当于Mock某个操作Materialize/Dematerialize
— 将发射的数据和通知都当做数据发射,或者反过来ObserveOn
— 指定观察者观察Observable的调度程序(工作线程)Serialize
— 强制Observable按次序发射数据并且功能是有效的Subscribe
— 收到Observable发射的数据和通知后执行的操作SubscribeOn
— 指定Observable应该在哪个调度程序上执行TimeInterval
— 将一个Observable转换为发射两个数据之间所耗费时间的ObservableTimeout
— 添加超时机制,如果过了指定的一段时间没有发射数据,就发射一个错误通知Timestamp
— 给Observable发射的每个数据项添加一个时间戳Using
— 创建一个只在Observable的生命周期内存在的一次性资源
条件和布尔操作
这些操作符可用于单个或多个数据项,也可用于Observable
All
— 判断Observable发射的所有的数据项是否都满足某个条件Amb
— 给定多个Observable,只让第一个发射数据的Observable发射全部数据Contains
— 判断Observable是否会发射一个指定的数据项DefaultIfEmpty
— 发射来自原始Observable的数据,如果原始Observable没有发射数据,就发射一个默认数据SequenceEqual
— 判断两个Observable是否按相同的数据序列SkipUntil
— 丢弃原始Observable发射的数据,直到第二个Observable发射了一个数据,然后发射原始Observable的剩余数据SkipWhile
— 丢弃原始Observable发射的数据,直到一个特定的条件为假,然后发射原始Observable剩余的数据TakeUntil
— 发射来自原始Observable的数据,直到第二个Observable发射了一个数据或一个通知TakeWhile
— 发射原始Observable的数据,直到一个特定的条件为真,然后跳过剩余的数据
算术和聚合操作
这些操作符可用于整个数据序列
Average
— 计算Observable发射的数据序列的平均值,然后发射这个结果Concat
— 不交错的连接多个Observable的数据Count
— 计算Observable发射的数据个数,然后发射这个结果Max
— 计算并发射数据序列的最大值Min
— 计算并发射数据序列的最小值Reduce
— 按顺序对数据序列的每一个应用某个函数,然后返回这个值Sum
— 计算并发射数据序列的和
连接操作
一些有精确可控的订阅行为的特殊Observable
Connect
— 指示一个可连接的Observable开始发射数据给订阅者Publish
— 将一个普通的Observable转换为可连接的RefCount
— 使一个可连接的Observable表现得像一个普通的ObservableReplay
— 确保所有的观察者收到同样的数据序列,即使他们在Observable开始发射数据之后才订阅
转换操作
操作符决策树
几种主要的需求
- 直接创建一个Observable(创建操作)
- 组合多个Observable(组合操作)
- 对Observable发射的数据执行变换操作(变换操作)
- 从Observable发射的数据中取特定的值(过滤操作)
- 转发Observable的部分值(条件/布尔/过滤操作)
- 对Observable发射的数据序列求值(算术/聚合操作)
- .
这个页面展示了创建Observable的各种方法。
just( )
— 将一个或多个对象转换成发射这个或这些对象的一个Observablefrom( )
— 将一个Iterable, 一个Future, 或者一个数组转换成一个Observablerepeat( )
— 创建一个重复发射指定数据或数据序列的ObservablerepeatWhen( )
— 创建一个重复发射指定数据或数据序列的Observable,它依赖于另一个Observable发射的数据create( )
— 使用一个函数从头创建一个Observabledefer( )
— 只有当订阅者订阅才创建Observable;为每个订阅创建一个新的Observablerange( )
— 创建一个发射指定范围的整数序列的Observableinterval( )
— 创建一个按照给定的时间间隔发射整数序列的Observabletimer( )
— 创建一个在给定的延时之后发射单个数据的Observableempty( )
— 创建一个什么都不做直接通知完成的Observableerror( )
— 创建一个什么都不做直接通知错误的Observablenever( )
— 创建一个不发射任何数据的Observable
创建操作
Create
使用一个函数从头开始创建一个Observable
你可以使用
Create
操作符从头开始创建一个Observable,给这个操作符传递一个接受观察者作为参数的函数,编写这个函数让它的行为表现为一个Observable--恰当的调用观察者的onNext,onError和onCompleted方法。一个形式正确的有限Observable必须尝试调用观察者的onCompleted正好一次或者它的onError正好一次,而且此后不能再调用观察者的任何其它方法。
RxJava将这个操作符实现为
create
方法。建议你在传递给
create
方法的函数中检查观察者的isUnsubscribed
状态,以便在没有观察者的时候,让你的Observable停止发射数据或者做昂贵的运算。示例代码:
Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> observer) { try { if (!observer.isUnsubscribed()) { for (int i = 1; i < 5; i++) { observer.onNext(i); } observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } } } ).subscribe(new Subscriber<Integer>() { @Override public void onNext(Integer item) { System.out.println("Next: " + item); } @Override public void onError(Throwable error) { System.err.println("Error: " + error.getMessage()); } @Override public void onCompleted() { System.out.println("Sequence complete."); } });
输出:
Next: 1 Next: 2 Next: 3 Next: 4 Sequence complete.
create
方法默认不在任何特定的调度器上执行。- Javadoc: <a rel="nofollow" href="http://reactivex.io/RxJava/javadoc/rx/Observable.html#create(rx.Observable.OnSubscribe)" "="" style="box-sizing: border-box; color: rgb(45, 133, 202); text-decoration: none; background-color: transparent;">
create(OnSubscribe)
Defer
直到有观察者订阅时才创建Observable,并且为每个观察者创建一个新的Observable
Defer
操作符会一直等待直到有观察者订阅它,然后它使用Observable工厂方法生成一个Observable。它对每个观察者都这样做,因此尽管每个订阅者都以为自己订阅的是同一个Observable,事实上每个订阅者获取的是它们自己的单独的数据序列。在某些情况下,等待直到最后一分钟(就是知道订阅发生时)才生成Observable可以确保Observable包含最新的数据。
RxJava将这个操作符实现为
defer
方法。这个操作符接受一个你选择的Observable工厂函数作为单个参数。这个函数没有参数,返回一个Observable。defer
方法默认不在任何特定的调度器上执行。- Javadoc: <a rel="nofollow" href="http://reactivex.io/RxJava/javadoc/rx/Observable.html#defer(rx.functions.Func0)" "="" style="box-sizing: border-box; color: rgb(45, 133, 202); text-decoration: none; background-color: transparent;">
defer(Func0)
switchCase
可选包
rxjava-computation-expressions
中有一个类似的操作符。switchCase
操作符有条件的创建并返回一个可能的Observables集合中的一个。可选包
rxjava-computation-expressions
中还有一个更简单的操作符叫ifThen
。这个操作符检查某个条件,然后根据结果,返回原始Observable的镜像,或者返回一个空Observable。Empty/Never/Throw
Empty
创建一个不发射任何数据但是正常终止的Observable
Never
创建一个不发射数据也不终止的Observable
Throw
创建一个不发射数据以一个错误终止的Observable
这三个操作符生成的Observable行为非常特殊和受限。测试的时候很有用,有时候也用于结合其它的Observables,或者作为其它需要Observable的操作符的参数。
RxJava将这些操作符实现为
empty
,never
和error
。error
操作符需要一个Throwable
参数,你的Observable会以此终止。这些操作符默认不在任何特定的调度器上执行,但是empty
和error
有一个可选参数是Scheduler,如果你传递了Scheduler参数,它们会在这个调度器上发送通知。- Javadoc: [empty()](http://reactivex.io/RxJava/javadoc/rx/Observable.html#never())
- Javadoc: <a rel="nofollow" href="http://reactivex.io/RxJava/javadoc/rx/Observable.html#error(java.lang.Throwable)" "="" style="box-sizing: border-box; color: rgb(45, 133, 202); text-decoration: none; background-color: transparent;">error(java.lang.Throwable)
From
将其它种类的对象和数据类型转换为Observable
当你使用Observable时,如果你要处理的数据都可以转换成展现为Observables,而不是需要混合使用Observables和其它类型的数据,会非常方便。这让你在数据流的整个生命周期中,可以使用一组统一的操作符来管理它们。
例如,Iterable可以看成是同步的Observable;Future,可以看成是总是只发射单个数据的Observable。通过显式地将那些数据转换为Observables,你可以像使用Observable一样与它们交互。
因此,大部分ReactiveX实现都提供了将语言特定的对象和数据结构转换为Observables的方法。
在RxJava中,
from
操作符可以转换Future、Iterable和数组。对于Iterable和数组,产生的Observable会发射Iterable或数组的每一项数据。示例代码
Integer[] items = { 0, 1, 2, 3, 4, 5 }; Observable myObservable = Observable.from(items); myObservable.subscribe( new Action1<Integer>() { @Override public void call(Integer item) { System.out.println(item); } }, new Action1<Throwable>() { @Override public void call(Throwable error) { System.out.println("Error encountered: " + error.getMessage()); } }, new Action0() { @Override public void call() { System.out.println("Sequence complete"); } } );
输出
0 1 2 3 4 5 Sequence complete
对于Future,它会发射Future.get()方法返回的单个数据。
from
方法有一个可接受两个可选参数的版本,分别指定超时时长和时间单位。如果过了指定的时长Future还没有返回一个值,这个Observable会发射错误通知并终止。from
默认不在任何特定的调度器上执行。然而你可以将Scheduler作为可选的第二个参数传递给Observable,它会在那个调度器上管理这个Future。- Javadoc: from(Iterable)
- Javadoc: from(Future,Scheduler)
- Javadoc: Start 查看关于这些操作符的更多信息。
注意:还有一个可选的
StringObservable
类中也有一个from
方法,它将一个字符流或者一个REader转换为一个发射字节数组或字符串的Observable。runAsync2
注意:这里与后面
start
操作符里的runAsync
说明重复了在单独的
RxJavaAsyncUtil
包中(默认不包含在RxJava中),还有一个runAsync
函数。传递一个Action
和一个Scheduler
给runAsync
,它会返回一个StoppableObservable
,这个Observable使用Action
产生发射的数据项。传递一个
Action
和一个Scheduler
给runAsync
,它返回一个使用这个Action
产生数据的StoppableObservable
。这个Action
接受一个Observable
和一个Subscription
作为参数,它使用Subscription
检查unsubscribed
条件,一旦发现条件为真就立即停止发射数据。在任何时候你都可以使用unsubscribe
方法手动停止一个StoppableObservable
(这会同时取消订阅与这个StoppableObservable
关联的Subscription
)。由于
runAsync
会立即调用Action
并开始发射数据,在你创建StoppableObservable之后到你的观察者准备好接受数据之前这段时间里,可能会有一部分数据会丢失。如果这不符合你的要求,可以使用runAsync
的一个变体,它也接受一个Subject
参数,传递一个ReplaySubject
给它,你可以获取其它丢失的数据了。decode
StringObservable
类不是默认RxJava的一部分,包含一个decode
操作符,这个操作符将一个多字节字符流转换为一个发射字节数组的Observable,这些字节数组按照字符的边界划分。