今年年初开始尝试使用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系列的文章