简介
ReactiveX 是一个通过使用可观察序列来组合通过或异步的基于事件处理的程序的库。
它扩展了观察者模式以支持数据或事件的序列,并添加了允许您以声明方式将序列组合在一起的运算符,同时抽象出对、同步、异步、线程安全并发数据结构和非阻塞 I/O的功能。
是一种函数式+响应式编程模式,有时也被称为“函数响应式编程”!
官网
Github
ReactiveX 生态系统
RxSwift 是 Rx 的 Swift 版本。而Rx的全称叫做 ReactiveX(简写: Rx),是一个跨平台框架。它不仅可以用来写 iOS ,你还可以用它来写 Android,Web 前端和后台。并且每个平台都和 RxSwift 一样有一套 Rx 生态系统。Rx 支持多种编程语言,如:Swift、Java、Php、JS、C#、Scala、Kotlin、Go 等。只要你掌握了其中一门语言,你很容易就能够熟悉其他的语言。
多语言支持
learn once, use anywhere
目前支持的语言
Languages
- Java: RxJava
- JavaScript: RxJS
- C#: Rx.NET
- C#(Unity): UniRx
- Scala: RxScala
- Clojure: RxClojure
- C++: RxCpp
- Lua: RxLua
- Ruby: Rx.rb
- Python: RxPY
- Go: RxGo
- Groovy: RxGroovy
- JRuby: RxJRuby
- Kotlin: RxKotlin
- Swift: RxSwift
- PHP: RxPHP
- Elixir: reaxive
- Dart: RxDart
ReactiveX 对平台的封装框架
- RxNetty
- RxAndroid
- RxCocoa
RxSwift 生态系统
- RxDataSources - UITableView 和 UICollectionView 数据源
- RxGesture - 页面手势
- RxMKMapView - 地图
- RxCoreMotion - 陀螺仪
- RxAlamofire - 网络请求
- RxCoreData - CoreData 数据库
- RxRealm - Realm 数据库
- RxMediaPicker - 图片选择器
- Action - 行为
- RxWebKit - WebView
- RxEventHub - 全局通知
- RxSwiftExt - 添加一些有用的操作符
- 更多
了解几个概念
函数式编程
函数式编程是种编程范式,它需要我们将函数作为参数传递,或者作为返回值返还。我们可以通过组合不同的函数来得到想要的结果。
1 2 3 4 5 6 7
| userInterestTagList .filter({ $0.choose }) .compactMap{ $0.guideTagId } .foreach { print("选中的标签:\($0)") }
|
它使我们可以通过组合不同的方法,以及不同的函数来获取目标结果。替代传统的 for
循环嵌套处理。所以函数式编程的优点是显而易见的:
函数响应式编程
函数响应式编程是种编程范式。它是通过构建函数操作数据序列,然后对这些序列做出响应的编程方式。它结合了函数式编程以及响应式编程
数据绑定(订阅)
将可监听序列绑定到观察者上。
学习曲线
前期会有较大的学习成本,后期开发效率会极大提升。
原理分析
核心概念
- Observable - 产生事件(可监听序列)
- Observer - 响应事件(观察者)
- Operator - 创建变化组合事件(操作符)
- Disposable - 管理绑定(订阅)的生命周期(可被清除资源)
- Schedulers - 线程队列调配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| let text = usernameOutlet.rx.text.orEmpty.asObservable()
let passwordValid = text .map { $0.count >= minimalUsernameLength }
let observer = passwordValidOutlet.rx.isHidden
let disposable = passwordValid .subscribeOn(MainScheduler.instance) .observeOn(MainScheduler.instance) .bind(to: observer)
disposable.dispose()
let disposeBag = DisposeBag() disposable.disposed(by: disposeBag)
|
购买案例
1 2 3 4 5 6 7 8 9 10 11 12
| var userBalance = 5.0
var productPrice = 10.0
let canMakePurchase = userBalance >= productPrice print(canMakePurchase)
userBalance += 20 print(canMakePurchase)
|
使用RX
1 2
| let canMakePurchase = Observable.combinelAtest(userBalance, productPrice) .map { $0 >= $1 }
|
参考:NumbersViewController
Int举例
Int
和 Observable<Int>
的区别?
Int
属于独立的值,彼此没有任何关系,这些值只是时间上的静态信息。
Observable<Int>
表示的时间轴上的值
使用场景举例
参考文档
可监听序列的拓展类型(Observable)
- Single
- Completable
- Maybe
- Driver
- Signal
- ControlEvent
具体介绍见文档
观察者的拓展类型(Observer)
具体介绍见文档
既是可监听序列也是观察者(Observable&Observer)
- AsyncSubject
- PublishSubject
- ReplaySubject
- HehaviorSubject
- ControlProperty
特殊类型RxRelay
具体介绍见文档
常用操作符
全部操作符见文档
- debug 打印调试
- debounce 节流
- throttle 节流
- delay 延时
- distinctUntilChanged 截流未改变的值
- filter
- map
- merge 合并,单值输出
- combineLatest 合并,多值输出
- zip 组合(合并, 成对输入)
- observeOn 观察者线程
- subscribeOn 可监听执行线程
- retry 重试,期间不产生 error
- shareReplay 共享,并缓存n个元素
- skip 跳过几次
- takeUntil 监听成功,开始忽略(终止响应)
可被清除资源(Disposable)
- 手动释放
dispose()
- 绑定清除包自动释放
- 监听释放
takeUntil
具体介绍见文档
调度器(Schedulers)
调配切换
- 监听序列调配
subscribeOn
- 观察者调配
observeOn
可选调配选项
- MainScheduler:
- SerialDispatchQueueScheduler
- ConcurrentDispatchQueueScheduler:
- OperationQueueScheduler
具体介绍见文档
容错机制
- retry
- retryWhen
- catchError
具体介绍见文档
实例
MVVM
在使用RxSwift实现MVVM架构
Model
Model是应用程序的数据模型,它通常是从网络或本地数据库中获取的数据。在RxSwift中,Model可以被表示为Observable序列,它会在数据发生变化时自动发出通知。可以使用Observable.create方法创建Observable序列,然后在其内部实现数据获取逻辑。
ViewModel
ViewModel是Model和View之间的桥梁,它负责将Model转化为View可以理解的形式,并将View产生的事件反馈到Model中。在RxSwift中,ViewModel通常由多个Observable序列组成,这些序列可以对Model进行转化和过滤,然后输出给View进行展示。可以使用Observable.combineLatest等方法将多个Observable序列组合在一起。
View
View是用户界面的显示部分,它通常由ViewController或View实现。在RxSwift中,View可以通过订阅ViewModel中的Observable序列,来显示ViewModel输出的数据,并将用户的事件发送给ViewModel。
Controller
绑定ViewModel和View
绑定ViewModel和View的方式通常是通过RxSwift提供的bind方法,将ViewModel中的Observable序列和View中的控件绑定在一起。这样当ViewModel的输出序列发生变化时,View中相应的控件也会自动更新。
处理用户交互事件
在MVVM架构中,用户的交互事件通常是由View发送给ViewModel的。可以通过RxSwift提供的bind方法,将View中的控件和ViewModel中的相应事件序列绑定在一起,从而实现用户交互事件的处理。
总之,使用RxSwift可以更加方便地实现MVVM架构,将数据流和用户交互事件流的处理分离开来,使代码更加清晰、易于维护。
总结
RxSwift优势已经很明显了,合理的使用RxSwift会大大简化代码量和代码逻辑,同时RxSwift也有它存在的弊端:
- 前期学习成本会较高
- Debug调试难度可能会比平时高一些,断点调试的抽象程度复杂
有兴趣可以基于我们的框架使用Rx方式进行封装,如我们现在的下拉刷新动作,上拉加载动作,网络请求动作等等。。
EDN