RxJava 學習筆記(七) --- Filtering 過濾操作

1. Filter —> 只發射通過了謂詞測試的數據項

Filter操作符使用你指定的一個謂詞函數測試數據項,只有通過測試的數據纔會被髮射。

            enter image description here

示例代碼

Observable.just(1, 2, 3, 4, 5)
          .filter(new Func1<Integer, Boolean>() {
              @Override
              public Boolean call(Integer item) {
                return( item < 4 );
              }
          }).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.

filter默認不在任何特定的調度器上執行。

2. OfType —> ofType是filter操作符的一個特殊形式。它過濾一個Observable只返回指定類型的數據。

ofType默認不在任何特定的調度器上指定。

            enter image description here

示例代碼:

Observable.just(1,"sb",0.1f).ofType(String.class).subscribe(new Action1<String>() {
           @Override
           public void call(String s) {
               System.out.println(s);
           }
       });

輸出:

sb

3. Take —> 只發射開始的N項數據

            enter image description here

使用Take操作符讓你可以修改Observable的行爲,只返回前面的N項數據,然後發射完成通知,忽略剩餘的數據。

            enter image description here

如果你對一個Observable使用take(n)(或它的同義詞limit(n))操作符,而那個Observable發射的數據少於N項,那麼take操作生成的Observable不會拋異常或發射onError通知,在完成前它只會發射相同的少量數據。

示例代碼:

Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
          .take(4)
          .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.

take(int)默認不任何特定的調度器上執行。

take的這個變體接受一個時長而不是數量參數。它會丟發射Observable開始的那段時間發射的數據,時長和時間單位通過參數指定。

            enter image description here

take的這個變體默認在computation調度器上執行,但是你可以使用第三個參數指定其它的調度器。

4. TakeLast —> 只發射最後N個元素

takeLast操作符是把源Observable產生的結果的後n項提交給訂閱者,提交時機是Observable發佈onCompleted通知之時。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6,7).takeLast(2)
          .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: 6 
Next: 7 
Sequence complete.

5. TakeLastBuffer —> 將最後的N項數據當做單個數據發射

它和takeLast類似,,唯一的不同是它把所有的數據項收集到一個List再發射,而不是依次發射一個。

            enter image description here

示例代碼:

Observable.just(1,2,3,4).takeLastBuffer(2).subscribe(new Action1<List<Integer>>() {
           @Override
           public void call(List<Integer> integers) {

               String s = "";
               for(Integer str : integers){
                   s = s +str +",";
               }

               System.out.println(s);
           }
       });

輸出:

I/System.out: 3,4,

6. Skip —> 跳過開始的N項數據

抑制Observable發射的前N項數據

            enter image description here

使用Skip操作符,你可以忽略Observable發射的前N項數據,只保留之後的數據。

            enter image description here

skip的這個變體默認不在任何特定的調度器上執行。

示例代碼

Observable.just(1,2,3,4).skip(1).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出

2
3
4

            enter image description here

skip的這個變體接受一個時長而不是數量參數。它會丟棄原始Observable開始的那段時間發射的數據,時長和時間單位通過參數指定。

skip的這個變體默認在computation調度器上執行,但是你可以使用第三個參數指定其它的調度器。

7. SkipLast —> 跳過後面的N項數據

抑制Observable發射的後N項數據

            enter image description here

使用SkipLast操作符修改原始Observable,你可以忽略Observable發射的後N項數據,只保留前面的數據。

            enter image description here

使用SkipLast操作符,你可以忽略原始Observable發射的後N項數據,只保留之前的數據。注意:這個機制是這樣實現的:延遲原始Observable發射的任何數據項,直到它發射了N項數據。

示例代碼:

Observable.just(1,2,3,4).skipLast(1).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出

1
2
3

skipLast的這個變體默認不在任何特定的調度器上執行。

            enter image description here

還有一個skipLast變體接受一個時長而不是數量參數。它會丟棄在原始Observable的生命週期內最後一段時間內發射的數據。時長和時間單位通過參數指定。

注意:這個機制是這樣實現的:延遲原始Observable發射的任何數據項,直到自這次發射之後過了給定的時長。

skipLast的這個變體默認在computation調度器上執行,但是你可以使用第三個參數指定其它的調度器。

8. Distinct —> 過濾掉重複數據

Distinct的過濾規則是:只允許還沒有發射過的數據項通過。

            enter image description here

在某些實現中,有一些變體允許你調整判定兩個數據不同(distinct)的標準。還有一些實現只比較一項數據和它的直接前驅,因此只會從序列中過濾掉連續重複的數據。

distinct()

            enter image description here

示例代碼:

Observable.just(1, 2, 1, 1, 2, 3)
          .distinct()
          .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.

distinct(Func1)

            enter image description here

這個操作符有一個變體接受一個函數。這個函數根據原始Observable發射的數據項產生一個Key,然後,比較這些Key而不是數據本身,來判定兩個數據是否是不同的。

示例代碼:

Observable.just(1,2,3,4,5,6).distinct(new Func1<Integer, Integer>() {
           @Override
           public Integer call(Integer integer) {
               return integer%3;
           }
       }).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出: 1% 3= 1 , 2%3 =2 ,3%3 = 0 , 4%3 = 1 , 5%3=2 ,6%3 = 0 ,後面三個和前面三個的值重複去掉

I/System.out: 1
I/System.out: 2
I/System.out: 3

9. DistinctUntilChanged —> 過濾掉連續重複的數據

DistinctUntilChanged()

            enter image description here

示例代碼:

Observable.just(1,2,2,2,5,6).distinctUntilChanged().subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出:

1
2
5
6

DistinctUntilChanged(Func1)

distinct(Func1)一樣,根據一個函數產生的Key判定兩個相鄰的數據項是不是不同的。

            enter image description here

示例代碼

Observable.just(1,2,2,2,5,11).distinctUntilChanged(new Func1<Integer, Integer>() {

           @Override
           public Integer call(Integer integer) {
               return integer %2;
           }
       }).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出

1
2
5

distinctdistinctUntilChanged默認不在任何特定的調度器上執行。

10. ElementAt —> 發射第N項數據

            enter image description here

ElementAt操作符獲取原始Observable發射的數據序列指定索引位置的數據項,然後當做自己的唯一數據發射。

            enter image description here

RxJava將這個操作符實現爲elementAt,給它傳遞一個基於0的索引值,它會發射原始Observable數據序列對應索引位置的值,如果你傳遞給elementAt的值爲5,那麼它會發射第項的數據。

如果你傳遞的是一個負數,或者原始Observable的數據項數小於index+1,將會拋出一個IndexOutOfBoundsException異常。

示例代碼:

Observable.just(1,2,3,4,5,6).elementAt(2)
          .subscribe(
                new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        System.out.println("Next:" + integer);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        System.out.println("Error:" + throwable.getMessage());
                    }
                }, new Action0() {
                    @Override
                    public void call() {
                        System.out.println("completed!");
                    }
                });

輸出:

Next:3 
completed!

11. ElementAtOrDefault —> 發射第N項數據,如果索引值大於數據項數,它會發射一個默認值(通過額外的參數指定)

RxJava還實現了elementAtOrDefault操作符。與elementAt的區別是,如果索引值大於數據項數,它會發射一個默認值(通過額外的參數指定),而不是拋出異常。但是如果你傳遞一個負數索引值,它仍然會拋出一個IndexOutOfBoundsException異常。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6).elementAtOrDefault(13,999).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出:

999

elementAt和elementAtOrDefault默認不在任何特定的調度器上執行。

12. First —> 只發射第一項數據

如果你只對Observable發射的第一項數據,或者滿足某個條件的第一項數據感興趣,你可以使用First操作符。

在某些實現中,First沒有實現爲一個返回Observable的過濾操作符,而是實現爲一個在當時就發射原始Observable指定數據項的阻塞函數。在這些實現中,如果你想要的是一個過濾操作符,最好使用Take(1)或者ElementAt(0)

在一些實現中還有一個Single操作符。它的行爲與First類似,但爲了確保只發射單個值,它會等待原始Observable終止(否則,不是發射那個值,而是以一個錯誤通知終止)。你可以使用它從原始Observable獲取第一項數據,而且也確保只發射一項數據。

RxJava中,這個操作符被實現爲first,firstOrDefaulttakeFirst

可能容易混淆,BlockingObservable也有名叫firstfirstOrDefault的操作符,它們會阻塞並返回值,不是立即返回一個Observable

還有幾個其它的操作符執行類似的功能。

First()

            enter image description here

示例代碼:

Observable.just(1, 2, 3)
          .first()
          .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
Sequence complete.

First(Func1)

傳遞一個謂詞函數給first,然後發射這個函數判定爲true的第一項數據。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6).first(new Func1<Integer, Boolean>() {
           @Override
           public Boolean call(Integer integer) {
               return integer>3;
           }
       }).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出

4

FirstOrDefault(T)

firstOrDefaultfirst類似,但是在Observable沒有發射任何數據時發射一個你在參數中指定的默認值。

            enter image description here

示例代碼:

Observable.empty().firstOrDefault("fuck you").subscribe(new Action1<Object>() {
           @Override
           public void call(Object o) {
               System.out.println(o+"");
           }
       });

輸出

fuck you

FirstOrDefault(T, Func1)

傳遞一個謂詞函數給firstOrDefault,然後發射這個函數判定爲true的第一項數據,如果沒有數據通過了謂詞測試就發射一個默認值。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6).firstOrDefault(99, new Func1<Integer, Boolean>() {
           @Override
           public Boolean call(Integer integer) {
               return integer == 4;
           }
       }).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出:

4

13. TakeFirst —> 返回一個可觀察到的發射僅由源觀測中滿足指定條件發射的第一個項目。

takeFirst操作符類似於take操作符,同時也類似於first操作符,都是獲取源Observable產生的結果列表中符合指定條件的前一個或多個,與first操作符不同的是,first操作符如果獲取不到數據,則會拋出NoSuchElementException異常,而takeFirst則會返回一個空的Observable,該Observable只有onCompleted通知而沒有onNext通知。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6,7).takeFirst(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                //獲取數值大於3的數據
                return integer>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: 4 
Sequence complete.

14. Single —> single操作符也與first類似

Single()

single操作符也與first類似,但是如果原始Observable在完成之前不是正好發射一次數據,它會拋出一個NoSuchElementException

            enter image description here

示例代碼:


Observable.just(1,2).single().subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println("===============>"+integer+"");
           }
       });

輸出

rx.exceptions.OnErrorNotImplementedException: Sequence contains too many elements

Single(Func1)

single的變體接受一個謂詞函數,發射滿足條件的單個值,如果不是正好只有一個數據項滿足條件,會以錯誤通知終止。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6).single(new Func1<Integer, Boolean>() {
           @Override
           public Boolean call(Integer integer) {
               return integer>5; // 輸出值爲6
               return integer>3; // 報錯 Sequence contains too many elements
               return integer>6; // 報錯 Sequence contains no elements
           }
       }).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer integer) {
               System.out.println(integer+"");
           }
       });

輸出:

return integer>5; // 輸出值爲6
return integer>3; // 報錯 Sequence contains too many elements
return integer>6; // 報錯 Sequence contains no elements

singleOrDefault(T)

firstOrDefault類似,但是如果原始Observable發射超過一個的數據,會以錯誤通知終止。

            enter image description here

示例代碼:

Observable.just("1","233").singleOrDefault("fuck you two").subscribe(new Action1<Object>() {
           @Override
           public void call(Object o) {
               Log.i("sss",o+"");
           }
       });

輸出:

rx.exceptions.OnErrorNotImplementedException: Sequence contains too many elements

firstOrDefault(T, Func1)類似,如果沒有數據滿足條件,返回默認值;如果有多個數據滿足條件,以錯誤通知終止。

            enter image description here

示例代碼

Observable.just(1,2,3,4,5,6,7,8).singleOrDefault(666, new Func1<Integer, Boolean>() {
           @Override
           public Boolean call(Integer s) {
               return s>4;       //rx.exceptions.OnErrorNotImplementedException: Sequence contains too many elements
               return s>12;      // 666
               return s>7;       // 8
           }
       }).subscribe(new Action1<Object>() {
           @Override
           public void call(Object o) {
               Log.i("sss",o+"");
           }
       });

15. Last —> 只發射最後一項(或者滿足某個條件的最後一項)數據

            enter image description here

如果你只對Observable發射的最後一項數據,或者滿足某個條件的最後一項數據感興趣,你可以使用Last操作符。

在某些實現中,Last沒有實現爲一個返回Observable的過濾操作符,而是實現爲一個在當時就發射原始Observable指定數據項的阻塞函數。在這些實現中,如果你想要的是一個過濾操作符,最好使用TakeLast(1)。

RxJava中的實現是lastlastOrDefault

可能容易混淆,BlockingObservable也有名叫lastlastOrDefault的操作符,它們會阻塞並返回值,不是立即返回一個Observable

last()

            enter image description here

只發射最後一項數據,使用沒有參數的last操作符。

示例代碼:

Observable.just(1, 2, 3)
          .last()
          .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: 3
Sequence complete.

last(Func1)

            enter image description here

這個版本的last也是接受一個謂詞函數,返回一個發射原始Observable中滿足條件的最後一項數據的Observable

示例代碼:

Observable.just(1,2,3,4,5,6,7,8).last(new Func1<Integer, Boolean>() {
           @Override
           public Boolean call(Integer integer) {
               return integer < 6;
           }
        }).subscribe(new Action1<Integer>() {
           @Override
           public void call(Integer o) {
              Log.i("sss",o+"");
               tv.setText(""+o);
           }
        });

輸出:

5

lastOrDefault(T)

            enter image description here

lastOrDefaultlast類似,不同的是,如果原始Observable沒有發射任何值,它發射你指定的默認值。

示例代碼:

Observable.empty().lastOrDefault(99).subscribe(new Action1<Object>() {
            @Override
            public void call(Object o) {
                Log.i("sss",o+"");
            }
        });

輸出:

99

lastOrDefault(T,Fun1)

enter image description here

示例代碼:

Observable.just(1,2,3,4,5,6,7,8,9).lastOrDefault(99, new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                return integer > 10;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                Log.i("sss",o+"");
            }
        });

輸出:

999

16. Sample —> 定期發射Observable最近發射的數據項

Sample操作符定時查看一個Observable,然後發射自上次採樣以來它最近發射的數據。

在某些實現中,有一個ThrottleFirst操作符的功能類似,但不是發射採樣期間的最近的數據,而是發射在那段時間內的第一項數據。

RxJava將這個操作符實現爲samplethrottleLast

注意:如果自上次採樣以來,原始Observable沒有發射任何數據,這個操作返回的Observable在那段時間內也不會發射任何數據。

            enter image description here

sample的這個變體每當第二個Observable發射一個數據(或者當它終止)時就對原始Observable進行採樣。第二個Observable通過參數傳遞給sample

sample的這個變體默認不在任何特定的調度器上執行。

示例代碼:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    //前8個數字產生的時間間隔爲1秒,後一個間隔爲3秒
                    for (int i = 1; i < 9; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(1000);
                    }
                    Thread.sleep(2000);
                    subscriber.onNext(9);
                    subscriber.onCompleted();
                } catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .sample(2200, TimeUnit.MILLISECONDS)  //採樣間隔時間爲2200毫秒
                .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: 3
Next: 5
Next: 7
Next: 8
Next: 9
Sequence complete.

sample(別名throttleLast)的一個變體按照你參數中指定的時間間隔定時採樣(TimeUnit指定時間單位)。

sample的這個變體默認在computation調度器上執行,但是你可以使用第三個參數指定其它的調度器。

17. ThrottleFirst —> throttleFirst與throttleLast/sample不同,在每個採樣週期內,它總是發射原始Observable的第一項數據,而不是最近的一項。

            enter image description here

throttleFirst操作符默認在computation調度器上執行,但是你可以使用第三個參數指定其它的調度器。

示例代碼:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    //前8個數字產生的時間間隔爲1秒,後一個間隔爲3秒
                    for (int i = 1; i < 9; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(1000);
                    }
                    Thread.sleep(2000);
                    subscriber.onNext(9);
                    subscriber.onCompleted();
                } catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .throttleFirst(2200, TimeUnit.MILLISECONDS)  //採樣間隔時間爲2200毫秒
                .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: 4
Next: 7
Next: 9
Sequence complete.

18. ThrottleWithTimeout( ) or Debounce( ) —> 只有當Observable在指定的時間後還沒有發射數據時,才發射一個數據

Debounce操作符會過濾掉髮射速率過快的數據項。

RxJava將這個操作符實現爲throttleWithTimeoutdebounce

注意:這個操作符會接着最後一項數據發射原始ObservableonCompleted通知,即使這個通知發生在你指定的時間窗口內(從最後一項數據的發射算起)。也就是說,onCompleted通知不會觸發限流。

            enter image description here

throtleWithTimeout/debounce的一個變體根據你指定的時間間隔進行限流,時間單位通過TimeUnit參數指定。

這種操作符默認在computation調度器上執行,但是你可以通過第三個參數指定。

示例代碼:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    for (int i = 0; i < 10; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(i * 100);
                    }
                    subscriber.onCompleted();
                }catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .debounce(400, TimeUnit.MILLISECONDS)  
                .subscribe(
                        new Action1<Integer>() {
                            @Override
                            public void call(Integer integer) {
                                System.out.println("Next:" + integer);
                            }
                        }, new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                System.out.println("Error:" + throwable.getMessage());
                            }
                        }, new Action0() {
                            @Override
                            public void call() {
                                System.out.println("completed!");
                            }
                        });

輸出:

Next:4 
Next:5 
Next:6 
Next:7 
Next:8 
Next:9 
completed!

            enter image description here

debounce操作符的一個變體通過對原始Observable的每一項應用一個函數進行限流,這個函數返回一個Observable。如果原始Observable在這個新生成的Observable終止之前發射了另一個數據,debounce會抑制(suppress)這個數據項。

debounce的這個變體默認不在任何特定的調度器上執行。

19. Timeout —> 如果在一個指定的時間段後還沒發射數據,就發射一個異常

            enter image description here

timeout(long,TimeUnit)

如果原始Observable過了指定的一段時長沒有發射任何數據,Timeout操作符會以一個onError通知終止這個Observable

第一個變體接受一個時長參數,每當原始Observable發射了一項數據,timeout就啓動一個計時器,如果計時器超過了指定指定的時長而原始Observable沒有發射另一項數據,timeout就拋出TimeoutException,以一個錯誤通知終止Observable

這個timeout默認在computation調度器上執行,你可以通過參數指定其它的調度器。

示例代碼:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    for (int i = 0; i < 10; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(i*100);
                    }
                    subscriber.onCompleted();
                }catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .timeout(300,TimeUnit.MILLISECONDS)
                .subscribe(
                        new Action1<Integer>() {
                            @Override
                            public void call(Integer integer) {
                                System.out.println("Next:" + integer);
                            }
                        }, new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                System.out.println("Error:" + throwable.getMessage());
                            }
                        }, new Action0() {
                            @Override
                            public void call() {
                                System.out.println("completed!");
                            }
                        });

輸出:

Next:0
Next:1
Next:2
Next:3
Next:4
Error:null

timeout(long,TimeUnit,Observable)

這個版本的timeout在超時時會切換到使用一個你指定的備用的Observable,而不是發錯誤通知。它也默認在computation調度器上執行。

            enter image description here

示例代碼:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    for (int i = 0; i < 10; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(i*100);
                    }
                    subscriber.onCompleted();
                }catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .timeout(300,TimeUnit.MILLISECONDS,Observable.just(555))
                .subscribe(
                        new Action1<Integer>() {
                            @Override
                            public void call(Integer integer) {
                                System.out.println("Next:" + integer);
                            }
                        }, new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                System.out.println("Error:" + throwable.getMessage());
                            }
                        }, new Action0() {
                            @Override
                            public void call() {
                                System.out.println("completed!");
                            }
                        });

輸出:

Next:0
Next:1
Next:2
Next:3
Next:555
completed!

timeout(Func1)

            enter image description here
這個版本的timeout使用一個函數針對原始Observable的每一項返回一個Observable,如果當這個Observable終止時原始Observable還沒有發射另一項數據,就會認爲是超時了,timeout就拋出TimeoutException,以一個錯誤通知終止Observable

這個timeout默認在immediate調度器上執行。

            enter image description here

這個版本的timeout同時指定超時時長和備用的Observable。它默認在immediate調度器上執行。

            enter image description here

這個版本的time除了給每一項設置超時,還可以單獨給第一項設置一個超時。它默認在immediate調度器上執行。

            enter image description here

同上,但是同時可以指定一個備用的Observable。它默認在immediate調度器上執行。

20. IgnoreElements —> 丟棄所有的正常數據,只發射錯誤或完成通知

不發射任何數據,只發射Observable的終止通知

            enter image description here

IgnoreElements操作符抑制原始Observable發射的所有數據,只允許它的終止通知(onErroronCompleted)通過。

如果你不關心一個Observable發射的數據,但是希望在它完成時或遇到錯誤終止時收到通知,你可以對Observable使用ignoreElements操作符,它會確保永遠不會調用觀察者的onNext()方法。

RxJava將這個操作符實現爲ignoreElements

示例代碼:

Observable.just(1,2,3,4,5,6,7,8).ignoreElements()
          .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.");
              }
          });

輸出:

Sequence complete.
發佈了34 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章