今年年初開始嘗試使用Flutter
開發android APP,期間遇到了很多的坑,但總算是有驚無險。而在作Android原生開發時,RxAndroid
讓代碼爽到飛起。爲了找回那種熟悉的感受,特地將RxDart
引入到項目中。首先介紹一下RxDart
是什麼: RxDart
基於ReactiveX,由Dart
標準庫中Stream
擴展而成,是一個爲Dart語言提供響應式編程的庫。react
首先在pubspec.yaml
中添加依賴:android
dependencies:
rxdart: ^0.22.1+1
複製代碼
接下來咱們經過一段代碼來看一下如何使用RxDart
編程
Observable.just(1).listen(print);
>>>1
複製代碼
//建立一個被觀察者
var observable = Observable.just(1);
//建立一個觀察者
var observa = (int num) {
print(num);
};
//經過listen實現訂閱
observable.listen(observa);
複製代碼
這下就明朗了,做爲一個Android開發者,對這段代碼充滿親切感。簡直和RxJava一抹同樣!!!數組
RxDart提供了不少方法供咱們建立Observable,除了上文中的直接使用just工廠函數從單個值中建立
,還有如下幾種建立方法:bash
Observable(Stream.fromIterable([1, 2, 3, 4, 5])).listen(print);
Observable.periodic(Duration(seconds: 1), (x) => x.toString()).listen(print);
這段代碼每隔一秒鐘打印一個整數並加一toStream
方法將Future轉換爲Stream而後再建立:Observable.periodic(Duration(seconds: 1), (x) => x.toString()).listen(print);
Future<String> asyncFunction() async {
return Future.delayed(const Duration(seconds: 10), () => "十秒後的數據");
}
Observable.fromFuture(asyncFunction()).listen(print);
複製代碼
代碼輸出以下:async
Rx最爽的是什麼?固然是無處不在的操做符啦!我我的以爲操做符是Rx的靈魂,關於操做符原理你們能夠閱讀從源碼查看RxJava中的map和flatMap的用法和區別去了解。下面咱們經過幾個經常使用的操做符學習一下RxDart的操做符使用方法:編輯器
過濾操做符就是用來過濾掉Observable發射的一些數據,丟棄這些數據只保留過濾後的數據。函數
點了半天編輯器老是不自動補全Filterpost
Observable(Stream.fromIterable([1, 2, 3, 4, 5]))
.where((num) => num % 2 == 0)
.listen(print);
>>>2 4
複製代碼
若是咱們想跳過前三個數字,咱們可使用skip操做符:學習
Observable(Stream.fromIterable([1, 2, 3, 4, 5]))
.skip(3)
.listen(print);
>>> 4 5
複製代碼
和skip操做相反,若是咱們去掉後面三個數據,只輸出前面兩個數據:
Observable(Stream.fromIterable([1, 2, 3, 4, 5]))
.take(2)
.listen(print);
<<<1 2
複製代碼
若是咱們要過濾掉原始數據裏重複的項:
Observable(Stream.fromIterable([1, 2, 2, 2, 3, 3, 4, 5]))
.distinctUnique()
.listen(print);
>>> 1 2 3 4 5
複製代碼
過濾操做符就是用來過變換Observable發射的一些數據或者Observable自己,將被變換的對象轉換成爲咱們想要的。
首先說一下map
,依舊是實現一個基本的數據轉換,將數字翻倍:
Observable(Stream.fromIterable([1, 2, 3, 4, 5]))
.map((num) => num * 2)
.listen(print);
<<<2 4 6 8 10
複製代碼
接下來講一下flatMap
,取出一個由數組組成的數組中的元素:
var list1 = [1, 2, 3];
var list2 = [4, 5, 6];
var list3 = [7, 8, 9];
var listAll = [list1, list2, list3];
Observable(Stream.fromIterable(listAll))
.flatMap((listItem) => Observable(Stream.fromIterable(listItem)))
.listen(print);
<<<1 2 3 4 5 6 7 8 9
複製代碼
相似flatMap操做符,區別在於concatMap按次序鏈接而不是合併那些生成的Observables,而後產生本身的數據序列。 看看下面的代碼:
var list1 = [1, 2, 3];
var list2 = [4, 5, 6];
var list3 = [7, 8, 9];
var listAll = [list1, list2, list3];
var changeConcatMap = (List<int> listItem) {
print("concatMap開始變換了");
return Observable(Stream.fromIterable(listItem));
};
var changeFlatMap = (List<int> listItem) {
print("FlatMap開始變換了");
return Observable(Stream.fromIterable(listItem));
};
Observable(Stream.fromIterable(listAll))
.concatMap((listItem) => changeConcatMap(listItem))
.listen(print);
Observable(Stream.fromIterable(listAll))
.flatMap((listItem) => changeFlatMap(listItem))
.listen(print);
複製代碼
輸出結果爲:
在數據序列的開頭插入一條指定的項:
var observable = Observable(Stream.fromIterable([1, 2, 3, 4, 5]));
observable.startWith(9).listen(print);
>>>9 1 2 3 4 5
複製代碼
使用Merge操做符你能夠將多個Observables的輸出合併,就好像它們是一個單個的Observable同樣。可是可能會讓合併的Observables發射的數據交錯
Observable.merge([
Stream.fromIterable([1, 2]),
Stream.fromIterable([3, 4])
]).listen(print);
>>> 1 3 2 4
複製代碼
當兩個Observables中的任何一個發射了數據時,使用一個函數結合每一個Observable發射的最近數據項,而且基於這個函數的結果發射數據。
var observable1 = Observable.just(1);
var observable2 = Observable.just(2);
Observable.combineLatest([observable1, observable2], (num) => num)
.listen(print);
>>>[1,2]
複製代碼
mergeWith將多個被觀察者發射的流合併成一個流。數據按照被髮送的順序傳遞
var observable1 = Observable.just(1);
var observable2 = Observable.just(5);
var observable = Observable(Stream.fromIterable([1, 2, 3, 4, 5]));
observable
.mergeWith([observable2,observable1])
.listen(print);
>>> 1 5 1 2 3 4 5
複製代碼
這只是一片RxDart使用的入門教程的。本文並未深刻探討RxDart的實現原理和邏輯,由於這些原理基本和RxJava中的相似。感興趣的能夠去關注個人RxJava系列的文章