這篇章主要介紹Rxjava的輔助操作符
目錄
Delay
延遲一段指定的時間再發射來自Observable的發射物
Observable.just(1,2,3).delay(2000, TimeUnit.MILLISECONDS, Schedulers.trampoline()).subscribe(num -> System.out.println(num+""));
結果:
1
2
3
上面的結果是延遲兩秒發射,注意是每個數據都延遲了兩秒發射。
一參爲延遲的時間,二參爲時間單位,三參爲調度器表示在哪個線程調度。
Do
這系列操作符有好幾個,我只寫一個,後面都很容易明白了。
Observable.just(1,2,3)
.doOnNext(num ->System.out.println(num+"++"))
.subscribe(num -> System.out.println(num+"*"));
結果:
1++
1*
2++
2*
3++
3*
看上面的結果,一分析就明白了。doOnNext就是在onNext輸出前,執行你寫的操作。下面還有do的其他操作符
doOnSubscribe :訂閱前調用
doOnUnsubscribe:不訂閱前調用
doOnCompleted :完成前調用
doOnError:異常終止前調用
doOnTerminate:終止前調用,不管completed還是error
finallyDo: 終止後調用,不管completed還是error
Serialize
一個Observable可以異步調用它的觀察者的方法,可能是從不同的線程調用。這可能會讓Observable行爲不正確,它可能會在某一個onNext
調用之前嘗試調用onCompleted
或onError
方法,或者從兩個不同的線程同時調用onNext
方法。
這個暫時不寫例子,以後補上。看到這裏的朋友,也可以自己試一下寫demo,我也渴望參詳參詳。
TimeInterval
TimeInterval
操作符攔截原始Observable發射的數據項,替換爲發射表示相鄰發射物時間間隔的對象。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
for (int i = 0; i < 3; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
observableEmitter.onNext(i+"");
}
observableEmitter.onComplete();
}
}).timeInterval(Schedulers.trampoline())
.subscribe(new Consumer<Timed<String>>() {
@Override
public void accept(Timed<String> stringTimed) throws Throwable {
System.out.println(stringTimed.value() +"::" +stringTimed.time());
}
});
結果:
0::1005
1::1000
2::1009
timeInterval操作符,可以讓我們發射的數據轉換成Timed<?>類,這個對象的value()爲我們發射的數據的值,time()爲上一個數據和這個數據發射間的時間間隔(單位:毫秒),而第一項數據得到的時間爲訂閱到第一個發射的時間間隔。
Timeout
對原始Observable的一個鏡像,如果過了一個指定的時長仍沒有發射數據,它會發一個錯誤通知
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
observableEmitter.onNext(1);
Thread.sleep(1000);
observableEmitter.onNext(2);
Thread.sleep(1000);
observableEmitter.onNext(3);
Thread.sleep(3000);
observableEmitter.onNext(4);
}
}).timeout(2000, TimeUnit.MILLISECONDS).subscribe(num -> System.out.println(num+"*"), throwable -> {System.out.println(throwable.getMessage());});
結果:
1*
2*
3*
The source did not signal an event for 2000 milliseconds and has been terminated.
timeout設置一個超時時間,當兩個發射時間的間隔大於設定時間時,就會拋出異常。
Timestamp
給Observable發射的數據項附加一個時間戳
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
for (int i = 0; i < 3; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
observableEmitter.onNext(i+"");
}
observableEmitter.onComplete();
}
}).timestamp(Schedulers.trampoline())
.subscribe(new Consumer<Timed<String>>() {
@Override
public void accept(Timed<String> stringTimed) throws Throwable {
System.out.println(stringTimed.value() +"::" +stringTimed.time());
}
});
結果:
0::1573968123248
1::1573968124248
2::1573968125257
與TimeInterval有點相似,不過TimeInterval讓發射數據帶有時間間隔。而Timestamp讓我們發射的數據帶有發射時的時間戳。
To
將Observable轉換爲另一個對象或數據結構
Observable.just(1, 2, 3, 4).toList().subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Throwable {
System.out.println(integers.get(3)+"++");
}
});
結果:
4++
toList就是把我們發射的數據弄成一個列表然後給到觀察者。
Observable.just(1, 2, 3, 4).toMap(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Throwable {
return integer+"";
}
}).subscribe(new Consumer<Map<String, Integer>>() {
@Override
public void accept(Map<String, Integer> map) throws Throwable {
System.out.println(map.get("2")+"*");
}
});
結果:
2*
toMap就是把發射數據弄成一個map對象發射給訂閱者。而toMap裏面放的函數就是決定map的key。
Using
創建一個只在Observable生命週期內存在的一次性資源。這是官方說法,我只會按我自己理解說
Observable.using(new Supplier<Student>() {
@Override
public Student get() throws Throwable {
Student student = new Student("aaa");
return student;
}
}, new Function<Student, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Student student) throws Throwable {
return Observable.just(student.getName());
}
}, new Consumer<Student>() {
@Override
public void accept(Student student) throws Throwable {
System.out.println(student.getName()+"++");
}
}).subscribe(str -> System.out.println(str+"*"));
結果:
aaa*
aaa++
using函數裏面的參數,一參爲返回這次要回收的資源,二參爲把這個資源轉換爲observable,然後由這個observable來訂閱我們的觀察者,三參爲數據處理完畢後,資源進入的函數,你就可以對這個資源進行回收或其他處理。
上面代碼,我們創了一個名爲aaa的學生對象,然後第二參數我們返回一個以學生名字的String的observable。先進入onNext訂閱的邏輯輸出了aaa*,然後再到第三參數函數的處理。