從零開始的RxJava2.0教程(二)操作符
1. 前言
在上一篇中,我介紹了RxJava 2.0的一些基礎知識,同時也介紹了map()操作符。這篇blog將介紹許多RxJava中的操作符,RxJava的強大性就來自於它所定義的操作符。
首先先看一個例子:
2. 準備工作
假設我的 Flowable
發射的是一個列表,接收者要把列表內容依次輸出。根據上一篇blog的內容,你可以會寫出這樣的程式碼:
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(1);
list.add(5);
Flowable.just(list)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> list) throws Exception {
for (Integer integer : list)
System.out.println(integer);
}
});
這樣的程式碼當然是不能容忍的,因為上面的程式碼使我們喪失了變化資料流的能力。一旦我們想要更改列表中的每一個數據,只能在訂閱者中做。
當然我們可以使用map
來中間處理,但是這樣做也需要遍歷整個list。
萬幸,RxJava 2.0 提供了fromIterable
方法,可以接收一個 Iterable
容器作為輸入,每次發射一個元素。
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(1);
list.add(5);
Flowable.fromIterable(list)
.subscribe(num -> System.out.println(num));
我們把fromX
用到這個例子中來。
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(1);
list.add(5);
Flowable.just(list)
.subscribe(nums -> {
Observable.fromIterable(nums)
.subscribe(num -> System.out.println(num));
});
雖然去掉了 for
迴圈,但是程式碼依然看起來很亂。嵌套了兩層,它會破壞某些我們現在還沒有講到的RxJava的特性。
3. 改進
救星來了,他就是 flatMap()
。
Flowable.flatMap
可以把一個 Flowable
轉換成另一個 Flowable
:
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(1);
list.add(5);
Flowable.just(list)
.flatMap(new Function<List<Integer>, Publisher<Integer>>() {
@Override
public Publisher<Integer> apply(List<Integer> integers) throws Exception {
return Flowable.fromIterable(integers);
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
和 map
不同之處在於 flatMap
返回的是一個 Flowable
物件。這正是我們想要的,我們可以把從List發射出來的一個一個的元素髮射出去。
4. 更多操作符
目前為止,我們已經接觸了兩個操作符,RxJava中還有更多的操作符。
如果我們想要訂閱者只能收到大於5的資料,那麼你可以這樣做:
Flowable.fromArray(1, 20, 5, 0, -1, 8) .filter(new Predicate<Integer>() { @Override public boolean test(Integer integer) throws Exception { return integer.intValue() > 5; } }) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { System.out.println(integer); } });
filter
是用於過濾資料的,返回false表示攔截此資料。如果我們只想要2個數據:
Flowable.fromArray(1, 2, 3, 4) .take(2) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { System.out.println(integer); } });
take
用於指定訂閱者最多收到多少資料。如果我們想在訂閱者接收到資料前乾點事情,比如記錄日誌:
Flowable.just(1, 2, 3) .doOnNext(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { System.out.println("儲存:" + integer); } }) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { System.out.println(integer); } });
doOnNext
允許我們在每次輸出一個元素之前做一些額外的事情。
5. 總結
如果你是從第一篇一直跟著敲程式碼,堅持到敲完了這一篇。
我相信你應該開始對RxJava 2.0 有感覺了。
別緊張,教程還未終結。