RxSwift分享1
什么是响应式编程
- 响应式编程是一种和事件流有关的编程模式,关注导致状态值改变的行为事件,一系列事件组成了事件流。
- 一系列事件是导致属性值发生变化的原因。响应式编程非常类似于设计模式里的观察者模式。
- 响应式编程与普通的函数式编程相似,但是每个函数可以接收一个输入值的流,如果其中,一个新的输入值到达的话,这个函数将根据最新的输入值重新计算,并且产生一个新的输出。这是一种”数据流”编程模式。
- 事件流
持续的事件 + 一条事件链 - 观察者模式
- 输入输出(数据流 例)
map/fitter + input/output(这两个维度)
响应式编程最初是为了简化交互式用户界面的创建和实时系统动画的绘制而提出来的一种方法,但它本质上是一种通用的编程范式。
为什么是响应式编程
- 开发过程中,状态以及状态之间依赖过多,响应式更加有效率地处理事件流,而无需显式去管理状态。过程式编程中,状态变化是最难跟踪,最头痛的事。这个也是最重要的一点。
- 减少变量的使用,由于它跟踪状态和值的变化,因此不需要再申明变量不断地观察状态和更新值。
- 提供统一的消息传递机制,将通知,代理,action,KVO以及其它所有UIControl事件的变化都进行监控,当变化发生时,就会传递事件和值。
- 当值随着事件变换时,可以使用map,filter,reduce等函数便利地对值进行变换操作。
- 状态????
- 减少变量
- 统一消息传递机制
- 好用的操作符
自己对于响应式的理解(例 看V,VM)
驱动+MVVM
移动端
MVC导致的V的冗余
MVVM
VM对于数据的处理->单元测试,解耦合
响应式剥离数据的处理到VM,只留下处理完成的数据和UI的绑定关系
数据和UI的交互
数据驱动UI
怎么记忆RxSwift的套路
Observable<Int>.create { observer in
1 ..... 产生事件
}
.map { element -> String in
2 ...... 操作事件
}
.subscribe(onNext: { element in
3 ...... 响应事件
}).disposed(by: disposeBag)
产生事件: Observable<Int>.create(...)
操作事件: map(),filter(), zip() 等操作符的功能
响应事件:subscribe(onNext: ..., onCompleted: ..., onError: ...)
万能公式 (例)
被观察者 + bind/drive/subscribe + 观察者
被观察者.onnext(“aaa”) / .accept(“aaa”)
实际使用->几乎都是 Subjects
wayBillListCommand
1.为什么项目中都是Subjects
既可以当观察者,又可以当被观察者
既可以写在前面,又可以写在后面
2.最常用的两种subjects
PublishSubject: 它不需要初始值就能创建
BehaviorRelay:保留上一次的值,用在列表,数组里面
被观察者(Observable)
1)创建
1Observable.create
例子+初学observer困惑
2 学习语法的时候也没有监听改变,观察者就跑起来了
self.bottomView.rx.selectControlEvent
a 关于Observable.create
b 怎么去进行一个包装
c 为什么要去这样包装
2)封装事件,对于事件,协议
3)为什么要将事件和协议封装为可观察序列
观察者(Observer)
1)创建
1 bind和subscribe的区别
output.nextVCData.subscribe
subscribe
self.refresh?.asObservable().bind(to: input.wayBillListCommand).disposed(by: rx.disposeBag)
直接驱动观察者的回调
2)创建拓展,binder
bindBottomView
3)为什么要拓展
RxCocoa,让controller里面的代码看上去更加精简
Driver
output.wayBillListData.asDriver().drive
self.mTableView.rx.itemSelected.asDriver()
1)不会产生error事件
2)一定在主线程监听
3)共享状态变化
https://juejin.im/post/5d44e7e051882579fd29104d
操作符
1、变换操作符:buffer、map、compactMap(原flatMap)、Scan等
https://www.jianshu.com/p/c665d49c5c72
2、过滤操作符:filter、take、skip等
https://www.jianshu.com/p/6c593dc9091f
3、条件和布尔操作符:amb、takeWhile、skipWhile等
https://www.jianshu.com/p/71b413d346c5
4、结合操作符:startWith、merge、zip等
https://www.jianshu.com/p/fde3d0109639
5、算数、以及聚合操作:toArray、reduce、concat
https://www.jianshu.com/p/dd0ce2de7056
6、连接操作符:connect、publish、replay、multicast
https://www.jianshu.com/p/64d5a52f222b
7、其他操作符:delay、materialize、timeout等
https://www.jianshu.com/p/2c69113856d2
案例
merge
Observable.of(self.customView.cancelBtn.rx.tap, self.customView.sureBtn.rx.tap).merge()
只有要merge的一个条件改变,就会触发回调,回调的就是当前改的那个被观察者的值
image.pngcombineLatest
Observable.combineLatest(self.nameTextFeild.rx.value, self.phoneNumFeild.rx.value)
需要combinelast里面的被观察者都被触发,才会触发回调,回调的就是当前改的那个被观察者的值以及另外的被观察者之前的值
image.pngZIP
凑齐再发车,发车能拿到两个被观察者的值
image.png在Rxdatasource里面,我们的cell点击事件比较僵硬的是,用itemselected和modelselected只能分别拿到indexpath和model,当我们想要两个值的时候,就可以用到zip了
7341567049764_.pic.jpg
throttle
cell.textField.rx.text.throttle
防止用户不间断的输入,导致不间断的请求。
在用户输入内容之后0.2内没有继续输入,就进行请求,如果0.2内有输入,就会将之前的被观察到的值给干掉
map
self.bottomView.rx.nextControlEvent.map
map也可以无中生有
compactMap
拍平操作,将多维数组拍平
model.stopPoints = [vc.input.loadPlace.value, vc.input.stopPointPlace.value, vc.input.deliveyPlace.value] .compactMap {$0}
希望大家有灵机一动用到了好用的操作符场景和大家一起分享
调试困难问题
1 分清模块职责
- viewmodel 是用来处理intput+output的捆绑关系,网络请求,处理数据
- model 是用来处理数据,比如说拼接价钱的¥,地址省市区的拼接等等
- Controller是用来 绑定数据和UI的关系,以及触发input,监听output的改变
- 一般还有一个类扩展bind,controlevent
2 根据input跟着链去找,input的触发,找到input的回调,input的回调里面找到output的触发,再找到out的回调,这样链式的去找