引言
当我们谈RxJava时,我们谈些什么?
- 函数式编程、响应式编程
- Callback Hell (回调地狱)
- 配合Retorfit,用于Android网络请求
- 线程切换、点击防抖等等
这些概念,有些了解,有些不了解,总是晕乎乎的。接下来我们就去寻找答案。
从数学运算讲起
我们有一个数学函数 f(x)=(x+2)*3-4
,代码来实现它。
//前者:传统的过程式编程,可能这样写
var x = x + 2
x = x * 3
x = x - 4
return x
//后者:所谓函数式编程,可能这样写
return add(x,2).multiply(3).subtract(4)
//RxJava 怎么写
Observable
.just(x)
.map { it + 2 }
.map { it * 3 }
.map { it - 4 }
.subscribe { println(it) }
复制代码
在看一个例子,我们有一组数字(1,2,3,4,5) 统计大于3的数字个数
var values = arrayOf(1, 2, 3, 4, 5)
//前者:命令式/过程式编程
var count = 0;
for (value in values) {
if (value > 0) {
count++
}
}
return count
//后者:链式编程?
return values.filter { it > 3 }.count()
复制代码
�我们似乎感受到一些不同
- 前者:似乎在一步步把逻辑翻译计算执行过程
- 后者:脑子里面充斥着add,map,fliter,count这些函数,最后得到结果。
前世今生
函数式编程
函数式编程关心数据的映射,命令式编程关心解决问题的步骤
- 1920年代~1930年代理论基础 组合子逻辑 ( Moses Schönfinkel ,Haskell Curry)
- 1930年代理论基础 Lambda演算(Alonzo Church)
- 1950年代后期,John McCarthy在麻省理工学院,开发了早期的函数式语言LISP
- 1950年代~1980年代,各种函数式语言 IPL,APL,FP,ML,SASL,Miranda…
- 1990年 函数式语言 Haskell (在编程语言Miranda的基础上标准化)
![]() Alonzo Church(1903-1995) |
![]() Haskell Brooks Curry(1900-1982) |
---|
响应式编程
Reactive Programming
响应式编程(reactive programming)是一种基于数据流(data stream)和变化传递(propagation of change)的声明式(declarative)的编程范式
- 响应式编程范型基于Edward A. Lee和David G. Messerschmitt在1987年提出的Synchronous Data Flow,但是放松了实时限制。响应式编程范式加入了表示连续时变值的行为和表示离散值的事件。
For example, in a model–view–controller(MVC) architecture, reactive programming can facilitate changes in an underlying _model _that are reflected automatically in an associated view
函数式响应式编程
Functional Reactive Programming(FRP)
函数式响应式编程(FRP) 是一种采用函数式编程的基础部件(如map、reduce、filter等)进行响应式编程(异步数据流程编程)的编程范式
- 1997年最早提出,Conal Elliott and Paul Hudak在ICFP 97论文 《Functional Reactive Animation》
Conal Elliott 82年本科毕业于 UCSB College of Creative Studies(加州大学圣塔芭芭拉分校创意设计学院),90年博士毕业。目前也非常活跃,Github 2021年已经提交了600多次(截止4月份)。
2009年左右有人在stackover follow上问What is functional reactive programming? 这哥们顺势回答了一波。
他从设计的角度列举了一些FRP的设计理念:
- Dynamic/evolving values (i.e., values “over time”) are first class values in themselves. You can define them and combine them, pass them into & out of functions. I called these things “behaviors”.
动态和变化的值是”一等公民”.你可以定义和组合他们以及作为函数的输入输出。我称之“行为”。
- Behaviors are built up out of a few primitives, like constant (static) behaviors and time (like a clock), and then with sequential and parallel combination. _n_behaviors are combined by applying an n-ary function (on static values), “point-wise”, i.e., continuously over time.
行为由一些原语构成,比如 常量(静态)行为和时间(比如时钟)然后还有将其串行和并行的组合。
-
To account for discrete phenomena, have another type (family) of “events”, each of which has a stream (finite or infinite) of occurrences. Each occurrence has an associated time and value.
-
To come up with the compositional vocabulary out of which all behaviors and events can be built, play with some examples. Keep deconstructing into pieces that are more general/simple.
构成要素要通用且简介。
- So that you know you’re on solid ground, give the whole model a compositional foundation, using the technique of denotational semantics, which just means that (a) each type has a corresponding simple & precise mathematical type of “meanings”, and (b) each primitive and operator has a simple & precise meaning as a function of the meanings of the constituents.
慕课网有个帖子,对FRP有段说明:
FPR 将输入分为两个基础的部分:行为(behavior)和事件(events) 。这两个基本元素在函数响应式编程中都是第一类(first-class)值。 其中行为是随时间连续变化的数据,而事件则是基于离散的时间序列 。例如:在我们操作网页的时候,会触发很多的事件,包括点击,拖动,按键事件等。这些事件都是不连续的。对事件求值是没有意义的,所有我们一般要通过fromEvent,buffer等将其变成连续的行为来做进一步处理。
Conal Elliott (82年本科毕业于 UCSB College of Creative Studies 加州大学圣塔芭芭拉分校创意设计学院 )
Reactive Extensions 
Rx = Observables + Operators + Schedulers.
ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming ReactiveX提供可观测流的异步编程API,它的灵感来源于观察者模式、迭代器模式和函数编程这些优秀思想。ReactiveX作为一个通用库, 现在已经有多种语言的实现版本(都是开源的), 包含RxJava, RxCpp, RxSwift, RxKotlin, RxGroovy, RxJavaScript等
- 2010年左右,Microsoft Live Labs开发了Volta项目,后来labs解散了,volta项目也黄了。
- 2011年左右,Microsoft Cloud Programmability Team 借鉴或者说传承Volta中关于响应式扩展的部分,发明了Reactive Extensions,2011年6月21号,发布了最初针对.NET Framework的Rx.NET.
- 2012年,Microsoft Cloud Programmability Team又开源了Rx其他平台的实现(包括JavaScript和C++)
现在我们不得不提 Erik Meijer,(生于1963年4月18日,荷兰库拉索岛)是荷兰计算机科学家和企业家。
From 2000 to early 2013 在微软工作,搞过C#,Visual Basic,LINQ,Volta,领导过Microsoft Cloud Programmability Team。你要是说他是Rx之父,也不为过。
2013年初,Erik Meijer离开了微软,创立了Applied Duality Incorporated。在此期间,他与Facebook合作开发了Hack语言,与Netflix合作开发了RxJava库,并与Google合作开发了Dart语言。
[
](en.wikipedia.org/wiki/Erik_M…
Erik Meijer,(1963-至今,生于荷兰库拉索岛)
RxJava
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
- 2012年Netflix为了应对不断增长的业务需求开始将.NET Rx迁移到JVM上面。
- 2013年二月份,Ben Christensen 和 Jafar Husain发在Netflix技术博客的一篇文章第一次向世界展示了RxJava。
- 2013年末的时候,Netflix、Pivotal、Typesafe等公司的工程师们共同发起了制定“Reactive-Streams规范”的倡议和讨论,并在github上创建了reactive-streams-jvm项目。到2015年5月份,1.0版本的规范出炉。Netflix的RxJava、Scala编程语言的发明者Typesafe公司的Akka Stream、Java开发者都熟悉的Pivotal公司的Project Reactor、走在技术前沿的Vert.x等响应式开发库都遵循次规范。
- 2016年11月12日,RxJava的2.x发布,
- 按照Reactive-Streams规范进行了大量的重写,
- 新增Flowable支持backpressure,Observable不再支持此特性。
- 新增运算符优化Operator-Fusion.
- 2019年6月,RxJava3.x发布
这里我们需要提一下,RxJava 2.x的主要贡献者David Karnok 关于响应式编程以及运算符融合的一些思考
reactive-streams-jvm
public interface Publisher<T> {
void subscribe(Subscriber<? super T> s);
}
public interface Subscriber<T> {
void onSubscribe(Subscription s);
void onNext(T t);
void onError(Throwable t);
void onComplete();
}
public interface Subscription {
void request(long n);
void cancel();
}
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}
复制代码