1. 程式人生 > >從零開始的RxJava2.0教程(二)操作符

從零開始的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中還有更多的操作符。

  1. 如果我們想要訂閱者只能收到大於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. 如果我們只想要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 用於指定訂閱者最多收到多少資料。

  3. 如果我們想在訂閱者接收到資料前乾點事情,比如記錄日誌:

    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 有感覺了。
別緊張,教程還未終結。