RxJava正在Android開發者中變的越來越流行。唯一的問題就是上手不容易,尤其是大部分人之前都是使用命令式編程語言。但是一旦你弄明白了,你就會發現RxJava真是太棒了。
本人目前也正在學習階段,立此貼來記錄自己學習的歷程。下來來講講RxJava操作符。
操作符
操作符是為了解決對Observable對象的變換的問題,操作符用于在Observable和最終的Subscriber之間修改Observable發出的事件。RxJava提供了很多很有用的操作符。
Subscribers更應該做的事情是“響應”,響應Observable發出的事件,而不是去修改。
所以修改就交給操作符吧.
操作符我按照功能效果進行分類:
創建操作符
just(?) — 將一個或多個對象轉換成發射這個或這些對象的一個Observable
from(?)— 將一個Iterable, 一個Future, 或者一個數組轉換成一個Observable
repeat(?)— 創建一個重復發射指定數據或數據序列的Observable
repeatWhen(?)— 創建一個重復發射指定數據或數據序列的Observable,它依賴于另一個Observable發射的數據
create(?)— 使用一個函數從頭創建一個Observable
defer(?)— 只有當訂閱者訂閱才創建Observable;為每個訂閱創建一個新的Observable
range(?)— 創建一個發射指定范圍的整數序列的Observable
interval(?)— 創建一個按照給定的時間間隔發射整數序列的Observable
timer(?)— 創建一個在給定的延時之后發射單個數據的Observable
empty(?)— 創建一個什么都不做直接通知完成的Observable
error(?)— 創建一個什么都不做直接通知錯誤的Observable
never(?)— 創建一個不發射任何數據的Observable
變換操作符
map(?)— 對序列的每一項都應用一個函數來變換Observable發射的數據序列
flatMap(?), concatMap(?), and flatMapIterable(?)— 將Observable發射的數據集合變換為Observables集合,然后將這些Observable發射的數據平坦化的放進一個單獨的Observable
switchMap(?)— 將Observable發射的數據集合變換為Observables集合,然后只發射這些Observables最近發射的數據
scan(?)— 對Observable發射的每一項數據應用一個函數,然后按順序依次發射每一個值
groupBy(?)— 將Observable分拆為Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據
buffer(?)— 它定期從Observable收集數據到一個集合,然后把這些數據集合打包發射,而不是一次發射一個
window(?)— 定期將來自Observable的數據分拆成一些Observable窗口,然后發射這些窗口,而不是每次發射一項
cast(?)— 在發射之前強制將Observable發射的所有數據轉換為指定類型
過濾操作符
filter(?)— 過濾數據
takeLast(?)— 只發射最后的N項數據
last(?)— 只發射最后的一項數據
lastOrDefault(?)— 只發射最后的一項數據,如果Observable為空就發射默認值
takeLastBuffer(?)— 將最后的N項數據當做單個數據發射
skip(?)— 跳過開始的N項數據
skipLast(?)— 跳過最后的N項數據
take(?)— 只發射開始的N項數據
first(?) and takeFirst(?)— 只發射第一項數據,或者滿足某種條件的第一項數據
firstOrDefault(?)— 只發射第一項數據,如果Observable為空就發射默認值
elementAt(?)— 發射第N項數據
elementAtOrDefault(?)— 發射第N項數據,如果Observable數據少于N項就發射默認值
sample(?) or throttleLast(?)— 定期發射Observable最近的數據
throttleFirst(?)— 定期發射Observable發射的第一項數據
throttleWithTimeout(?) or debounce(?)— 只有當Observable在指定的時間后還沒有發射數據時,才發射一個數據
timeout(?)— 如果在一個指定的時間段后還沒發射數據,就發射一個異常
distinct(?)— 過濾掉重復數據
distinctUntilChanged(?)— 過濾掉連續重復的數據
ofType(?)— 只發射指定類型的數據
ignoreElements(?)— 丟棄所有的正常數據,只發射錯誤或完成通知
just操作符
創建一個發射指定值的Observable
ust將單個數據轉換為發射那個數據的Observable。
Just類似于From,但是From會將數組或Iterable的素具取出然后逐個發射,而Just只是簡單的原樣發射,將數組或Iterable當做單個數據。
注意:如果你傳遞null
給Just,它會返回一個發射null
值的Observable。不要誤認為它會返回一個空Observable(完全不發射任何數據的Observable),如果需要空Observable你應該使用Empty操作符。
RxJava將這個操作符實現為just
函數,它接受一至九個參數,返回一個按參數列表順序發射這些數據的Observable。
實例代碼:
Observable.just(1, 2, 3)
.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
Sequence complete.
from操作符
當你使用Observable時,如果你要處理的數據都可以轉換成展現為Observables,而不是需要混合使用Observables和其它類型的數據,會非常方便。這讓你在數據流的整個生命周期中,可以使用一組統一的操作符來管理它們。
例如,Iterable可以看成是同步的Observable;Future,可以看成是總是只發射單個數據的Observable。通過顯式地將那些數據轉換為Observables,你可以像使用Observable一樣與它們交互。
因此,大部分ReactiveX實現都提供了將語言特定的對象和數據結構轉換為Observables的方法。
在RxJava中,from
操作符可以轉換Future、Iterable和數組。對于Iterable和數組,產生的Observable會發射Iterable或數組的每一項數據。
實例代碼:
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");
}
});
repeat
Repeat重復地發射數據。某些實現允許你重復的發射某個數據序列,還有一些允許你限制重復的次數。

RxJava將這個操作符實現為repeat
方法。它不是創建一個Observable,而是重復發射原始Observable的數據序列,這個序列或者是無限的,或者通過repeat(n)
指定重復次數。
repeat
操作符默認在trampoline
調度器上執行。有一個變體可以通過可選參數指定Scheduler。
示例代碼:
Observable.just(1, 2, 3)
.repeat(3)//重復三次
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("Next: " +integer);
}
});
輸出
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 1
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 2
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 3
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 1
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 2
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 3
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 1
12-16 06:52:16.945 3164-3164/? I/System.out: Next: 2
12-16 06:52:16.946 3164-3164/? I/System.out: Next: 3
repeatWhen操作符
還有一個叫做repeatWhen
的操作符,它不是緩存和重放原始Observable的數據序列,而是有條件的重新訂閱和發射原來的Observable。
將原始Observable的終止通知(完成或錯誤)當做一個void
數據傳遞給一個通知處理器,它以此來決定是否要重新訂閱和發射原來的Observable。這個通知處理器就像一個Observable操作符,接受一個發射void
通知的Observable為輸入,返回一個發射void
數據(意思是,重新訂閱和發射原始Observable)或者直接終止(意思是,使用repeatWhen
終止發射數據)的Observable。
repeatWhen
操作符默認在trampoline
調度器上執行。有一個變體可以通過可選參數指定Scheduler。
Javadoc: repeatWhen(Func1)
Javadoc: repeatWhen(Func1,Scheduler)
doWhile操作符
whileDo屬于可選包rxjava-computation-expressions,不是RxJava標準操作符的一部分。whileDo在原始序列的每次重復前檢查某個條件,如果滿足條件才重復發射。
create操作符
你可以使用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: create(OnSubscribe)
defer操作符
直到有觀察者訂閱時才創建Observable,并且為每個觀察者創建一個新的Observable
Defer
操作符會一直等待直到有觀察者訂閱它,然后它使用Observable工廠方法生成一個Observable。它對每個觀察者都這樣做,因此盡管每個訂閱者都以為自己訂閱的是同一個Observable,事實上每個訂閱者獲取的是它們自己的單獨的數據序列。
在某些情況下,等待直到最后一分鐘(就是知道訂閱發生時)才生成Observable可以確保Observable包含最新的數據。

RxJava將這個操作符實現為 defer
方法。這個操作符接受一個你選擇的Observable工廠函數作為單個參數。這個函數沒有參數,返回一個Observable。
defer
方法默認不在任何特定的調度器上執行。
Javadoc: defer(Func0)
[
](https://github.com/jiang111/RxDocs/blob/master/operators/Defer.md#switchcase)switchCase
可選包 rxjava-computation-expressions
中有一個類似的操作符。switchCase
操作符有條件的創建并返回一個可能的Observables集合中的一個。

可選包 rxjava-computation-expressions
中還有一個更簡單的操作符叫ifThen
。這個操作符檢查某個條件,然后根據結果,返回原始Observable的鏡像,或者返回一個空Observable。
range操作符
Range操作符發射一個范圍內的有序整數序列,你可以指定范圍的起始和長度。
RxJava將這個操作符實現為range
函數,它接受兩個參數,一個是范圍的起始值,一個是范圍的數據的數目。如果你將第二個參數設為0,將導致Observable不發射任何數據(如果設置為負數,會拋異常)。
range
默認不在任何特定的調度器上執行。有一個變體可以通過可選參數指定Scheduler。
Javadoc: range(int,int)
Javadoc: range(int,int,Scheduler)
interval操作符
Interval
操作符返回一個Observable,它按固定的時間間隔發射一個無限遞增的整數序列。

RxJava將這個操作符實現為interval
方法。它接受一個表示時間間隔的參數和一個表示時間單位的參數。
Javadoc: interval(long,TimeUnit)
Javadoc: interval(long,TimeUnit,Scheduler)
還有一個版本的interval
返回一個Observable,它在指定延遲之后先發射一個零值,然后再按照指定的時間間隔發射遞增的數字。這個版本的interval
在RxJava 1.0.0中叫做timer
,但是那個方法已經不建議使用了,因為一個名叫interval
的操作符有同樣的功能。
Javadoc: interval(long,long,TimeUnit) Javadoc: interval(long,long,TimeUnit,Scheduler)
interval
默認在computation
調度器上執行。你也可以傳遞一個可選的Scheduler參數來指定調度器。
timer操作符
創建一個Observable,它在一個給定的延遲后發射一個特殊的值。
Timer
操作符創建一個在給定的時間段之后返回一個特殊值的Observable。
RxJava將這個操作符實現為timer
函數。
timer
返回一個Observable,它在延遲一段給定的時間后發射一個簡單的數字0。
timer
操作符默認在computation
調度器上執行。有一個變體可以通過可選參數指定Scheduler。
Javadoc: timer(long,TimeUnit)
Javadoc: timer(long,TimeUnit,Scheduler)
empty操作符
創建一個不發射任何數據但是正常終止的Observable
[
](https://github.com/jiang111/RxDocs/blob/master/operators/Empty.md#never)Never
創建一個不發射數據也不終止的Observable
[
](https://github.com/jiang111/RxDocs/blob/master/operators/Empty.md#throw)Throw
創建一個不發射數據以一個錯誤終止的Observable
這三個操作符生成的Observable行為非常特殊和受限。測試的時候很有用,有時候也用于結合其它的Observables,或者作為其它需要Observable的操作符的參數。
RxJava將這些操作符實現為 empty
,never
和error
。error
操作符需要一個Throwable
參數,你的Observable會以此終止。這些操作符默認不在任何特定的調度器上執行,但是empty
和error
有一個可選參數是Scheduler,如果你傳遞了Scheduler參數,它們會在這個調度器上發送通知。
Javadoc: empty()
Javadoc: never()
Javadoc: error(java.lang.Throwable)