RxSwift学习——Observable的操作符

1,077 阅读4分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

前言

通过前面几篇文章,我讲解了RxSwift中下面3大类型:

  • Observable(序列),可以用于产生异步元素或者同步元素的流水线

  • Observer(观察者),它是传感器,用于观察序列的一个类型,它可以对流水线上的元素做3种状态处理:next、error、completed。

  • Relay(既是序列也是观察者),它是继电器,它是上面两者的结合体,可以作为序列与观察者的连接器使用。

上一节的这张图已经很好的说明了3者的作用:

image.png

在实际的生产中的流水线,总是在干着这么一件事情:运输元素的时候,把元素改变为另外一种元素。

这也是我们这节要讲解的——序列的操作符。

操作符

比如我们生产活动中,把猪肉做成火腿肠就是一个例子:

  1. 流水线上面运输着猪肉。
  2. 猪肉运输到了一个加工车间。
  3. 从加工车间出来的就是火腿肠了。

image.png

这里用伪代码表示大概就是:

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个操作符函数感到害怕,它就像一般工具手册,你在需要使用某些功能,或者需要获得某种状态的时候,去翻一翻就可以。

  • 文档的决策树可能会帮上你的忙,不明白的时候去看看吧——决策树

  • 了解几种常用的操作符比较用:

    1. zip
    2. combineLatest
    3. flatMapLatest

总结

本节我讲解了Observable的操作符。

所谓的流水线呢就是这样,把原材料一步步的做成成品,在这期间可能需要多个流水线协调,需要通过阻挡器去协调不同流水线上的运输节奏,剔除掉原材料中的不良品。

上面做的一系列操作或者更多操作,我们在序列中都是通过操作符完成。

记住,序列经过操作符处理后,还是一个序列!它还没有走向终点,在subscribe里面的观察者,才是一个元素的最后旅程。

下一节预告

其实,我本来将写写RxSwift到Rx整个框架和工控等方面的思考,结果一不小心就把序列的操作符写了。

后面写啥,还不清楚,未完待续。

我参加的8月更文活动到此为止。

参考文档

Operator - 操作符

RxSwift编写wanandroid客户端现已开源

目前RxSwift编写wanandroid客户端已经开源了——项目链接

我进行了一轮CodeReview,并增加了一些小功能:

  • 添加了iOS的黑暗模式适配

  • 上拉加载更多使用了无感知功能

  • MBProgressHUD替换为SVProgressHUD

记得给个star喔!

附上一张效果图片:

RPReplay_Final1627969241.2021-08-03 13_44_57.gif