[翻译]RxSwift入门(1)

标题:RxSwift Primer: Part 1 ,作者 Casey Liss,2016-12-15
原文:https://www.caseyliss.com/2016/12/15/rxswift-primer-part-1

没取得版权,盗版翻译一下,英文水平烂,别在意细节

我入职这份工的时候,团队刚开始研究用响应式编程(Reactive Programming)重写我们的主App。对响应式编程闻所未闻的我立刻被勾起兴趣了。
于是我开始学习响应式编程,但是却找不到很好的入门指南来解惑。所以接下来的几篇文章,恕我斗胆来写一份。

今天,我们从基本的问题开始。什么是响应式编程?它带来了些什么变化?我为什么要在乎?

什么是Rx?

我把响应式编程(Rx)概括为:

把一个系统建模为由数据组成的一系列“流”,尽可能消除储存状态。

这个定义可能并不那么“学术”,但这就是我的看法。

响应式编程的关键在于,把所有事物都当作一系列输入和输出;尽可能当作异步的去想。我们可以把大多数系统建模——尤其是用户界面(user interfaces)和网络请求,看作是由可组合的流而串起来的(chains)。

Rx带来了什么?

  • 无状态编程

    每个程序内都很自然地拥有状态,但是Rx却致力于消除状态。相较于储存状态,Rx更希望简单地响应由外界引起的变化。这些变化可能是网络请求回调或是点击按钮这样的用户行为。

  • 更少bug

    消除了状态,我们就消除了通往bug的康庄大道。Bugs常常是由于所储存的状态与事物实际的状态不一致而导致的。举个例子,一个基于云的app,其本地用户数据与服务器上的用户数据不同步。当然,Rx也无法消除所有的状态,但它已经消除了很多了。

    即使尽可能简单地保持数据模型(data model)与UI控件的同步,有时依然会有bug。而Rx,通常不需储存任何东西,也就无需同步,意味着更少bug了。

  • 更好的逻辑推理

    Rx带来了一堆工具,有些我们已经见过了(高阶函数map),有些是全新的(如CombineLatest)。一旦你了解了这些工具,你就可以很容易地理解被怎样处理了。示例:

    self.button.rx.tap
    .withLatestFrom(segmentedControl.rx.value)
    .map { selectedIndex in
    return "You've selected #\(selectedIndex)."
    }
    .subscribe { message in
    print(message)
    }
    .addDisposableTo(disposeBag)

    上述代码,我们拿到一个button,在它被点击的时候做些事。先是读取一个UISegmentedControl的当前值。一旦拿到了值,我们在控制台(console)打印一条消息。
    我们组合了两个流:button点击和segment的值,然后把结果转换(mapping)成string。最后我们拿到这个string来做些操作。
    这些都可以从属性和函数调用一眼看出来:tapwithLatestFrom()valuemapsubscribe,显而易见嘛。

  • 提高灵活性和速度

    当你app中的所有东西都以流的形式暴露出来后,为已有的代码扩展添加新特性或响应新需求会变得很容易。很多本来颇具挑战性的业务需求也会变得十分简单,无非是各种流的如何组合罢了。

    就在前几天,我们遇到一个需求,客户希望当某些搜索过滤器被勾选后,让某个按钮变成enable状态。得益于过滤器值以流的形式暴露,可以简单地用withLatestFrom(filters).map {}使button根据过滤器的状态自动作出enable/disable响应,毫不费力。

  • 跨语言支持

    大多数现代编程语言都有Rx的原生实现。就我的工作来说,我们用RxSwift开发iOS,用RxJava来开发Android。如果你的开发语言不是Swift,也没问题。这些相同的理念和方法也应该通用于你选择的开发平台。你可以看看ReactiveX网站了解其支持的开发语言。

    Rx给我们带来的优势是:如果我们的Android小组解决了一个难题,那么我们iOS小组可以直接把他们的解决方案照搬过来,平台差异根本不影响。这非常棒,它使得我们拥有共同语言,尽管我们实际上用的开发语言迥然不同。

我为什么要在乎?

从2月开始就把RxSwift投入工作,我真的很喜欢它。它使我花了很长时间去忘记,忘记那些传统的编程方式方法。我还在努力着,把问题以更响应式的方向去理解。
综上所述,我已无法想象回到传统方式去写代码,让人感觉太笨重,臃肿,陈旧。

Rx是一种截然不同的思维方式,我还没见过有人用得很溜。我花了好几个月的时间才抓住重点,小有成效。相处接近一年,我就对它死心塌地了。


在接下来的几篇文章里,我会讨论一个枯燥无味的简单demo,把它从传统的,过程式的代码用Rx重新实现。一次一小步地进行。
这个demo是一个UIView,其包含了一个UIButton和一个UILabel。你点击button的时候,会在label上显示你点击了多少次。
看上去是很无聊,但是从设计上,它从传统的代码转变为最新颖的。我不想让界面上有其他无关紧要的东西影响了我们讨论的核心问题。

以下是demo app的动画演示(盗链的,别举报):



第二篇,我们将快速浏览代码,用原生的UIKit编写,然后进行初步转化到Rx