这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
前言
通过前面几篇文章,我讲解了RxSwift中下面3大类型:
-
Observable(序列),可以用于产生异步元素或者同步元素的
流水线
。 -
Observer(观察者),它是
传感器
,用于观察序列的一个类型,它可以对流水线
上的元素做3种状态处理:next、error、completed。 -
Relay(既是序列也是观察者),它是
继电器
,它是上面两者的结合体,可以作为序列与观察者的连接器使用。
上一节的这张图已经很好的说明了3者的作用:
在实际的生产中的流水线,总是在干着这么一件事情:运输元素的时候,把元素改变为另外一种元素。
这也是我们这节要讲解的——序列的操作符。
操作符
比如我们生产活动中,把猪肉做成火腿肠就是一个例子:
- 流水线上面运输着猪肉。
- 猪肉运输到了一个加工车间。
- 从加工车间出来的就是火腿肠了。
这里用伪代码表示大概就是:
Observable<猪肉> => Observable<火腿肠>。
让我们想想,如何将一个[01, 2, 3, 4, 5]数组转成字符串形式?
当然你可以用for循环,但是作为一个Swift的编程者,使用Swift自带的高阶函数,是一种自我修养:
let array = [0, 1, 2, 3, 4, 5]
let newArray = array.map { "\($0)" }
这样一个[Int]类型的数组,就被加工
成了一个[String]类型的数组了。
回想一下,我在讲解Observable(序列)的时候,类比过数组的,既然数组有map函数,那么Observable会有吗?
有的!而且用法几乎如出一辙:
let observable = Observable.from([0, 1, 2, 3, 4, 5])
let newObservable= observable.map { "\($0)" }
到此,我们就将一个Observable<Int>
类型的序列转成了Observable<String>
类型的序列,而map则是序列中一个操作符。
流水线的作用不仅是用于传输元素,同时肩负着预处理、加工的职能,在最终给到观察者之前,我们要尽量好的把最终形态给到观察者,这样最后观察者使用元素起来就很快乐。
这个最经典的例子算是网络请求,我们一般希望在赋值给UI的数据是Model,而不是JSON,我们一般都会在某个中间层,做一次JSON转Model,这个JSON->Model的变化,我们在RxSwift中,也就是一次次加工而成。
下面是我写wanandroid项目中,一个接口的网络请求的代码:
homeProvider.rx.request(HomeService.queryKeyword(keyword, page))
/// JSON加工成BaseModel<Page<Info>>的Model,形成新的序列
.map(BaseModel<Page<Info>>.self)
/// 获取Model中的data值,形成新的序列
.map{ $0.data }
/// 过滤掉nil,形成新的序列,注意compactMap之后,Single变成了Maybe类型
.compactMap { $0 }
/// 转成Observable
.asObservable()
/// 最后再转成Single输出
.asSingle()
这段代码里面使用2次map和1次compactMap,目的就是为了获得一个舒服的
数据,使得ViewModel层在与View做绑定的时候,更加平滑。
ViewModel层做处理数据,View层只做数据绑定。
注意事项
上面讲了这么多,只讲了RxSwift中序列操作符中最简单、最基本的一个——map,而序列有多达57个操作符(中文文档展示的)。
我想,我要是每个都讲一遍,以我的更文速度,一年都不一定写的完。
另外,就是这么多操作符,只有在特地的业务场景才会使用,光讲不练,得不任何收获,不如要用的时候再去寻找与尝试。
对于这些操作符,我给下面几点建议:
-
了解Swift自身的高阶函数使用,自身的高阶函数弄明白了,其实RxSwift的这些操作符就不困难了。
-
不要对于57个操作符函数感到害怕,它就像一般工具手册,你在需要使用某些功能,或者需要获得某种状态的时候,去翻一翻就可以。
-
文档的决策树可能会帮上你的忙,不明白的时候去看看吧——决策树。
-
了解几种常用的操作符比较用:
- zip
- combineLatest
- flatMapLatest
总结
本节我讲解了Observable的操作符。
所谓的流水线呢就是这样,把原材料一步步的做成成品,在这期间可能需要多个流水线协调,需要通过阻挡器去协调不同流水线上的运输节奏,剔除掉原材料中的不良品。
上面做的一系列操作或者更多操作,我们在序列中都是通过操作符完成。
记住,序列经过操作符处理后,还是一个序列!它还没有走向终点,在subscribe里面的观察者,才是一个元素的最后旅程。
下一节预告
其实,我本来将写写RxSwift到Rx整个框架和工控等方面的思考,结果一不小心就把序列的操作符写了。
后面写啥,还不清楚,未完待续。
我参加的8月更文活动到此为止。
参考文档
RxSwift编写wanandroid客户端现已开源
目前RxSwift编写wanandroid客户端已经开源了——项目链接。
我进行了一轮CodeReview,并增加了一些小功能:
-
添加了iOS的黑暗模式适配
-
上拉加载更多使用了无感知功能
-
MBProgressHUD替换为SVProgressHUD
记得给个star喔!
附上一张效果图片: