第一篇 介绍ReactiveX

1,999 阅读6分钟

前言

学习RxSwift之前,需要了解一下ReactiveX,因为ReactiveX维护了绝大多数语言的响应式框架。这些语言采用统一的风格和思想,所以要想深入了解响应式框架的原理,您最好先了解一下ReactiveX,有兴趣的同学也可以去官网读一下官方的介绍。

ReactiveX

ReactiveX是一个库,通过可观察序列的方式 编写异步和基于事件的应用程序。
它对观察者模式进行了扩展,从而支持数据和事件的序列化。并且添加了操作符,允许您以声明的方式将序列组合在一起。同时让你不必再关注低级线程、同步、线程安全、并发数据结构和非阻塞I/O等问题.

访问多个项目的异步序列是不太容易的,ReactiveX作为一种理想的方式解决了这个问题,进而填补了这个空白

image.png

它有时被称为函数响应式编程,但这是不准确的。因为ReactiveX既可以是函数式的也可以是响应式的。一个主要的区别是,函数反应式编程对随时间连续变化的值进行操作,而ReactiveX对随时间发出的分散的值进行操作。(有关函数反应式编程的更精确信息,请参阅这里。)

为什么使用Observables?

因为ReactiveX可观察模型允许你处理异步事件流,就像使用数组收集数据一样简单。它将您从错综复杂的回调网络中解放出来,从而使您的代码更具可读性,更不容易出现错误。

Observables是可以进行组合的

像 Java Futures这样的技术,可以直接处理单一级别的异步任务。但是当任务嵌套时,就会变得越来越复杂,极易形成嵌套地狱,不易于维护。
对于异步执行任务,使用Futures是很难进行优化的(或者不可能,因为每个请求的延迟在运行时会有所不同)。当然,这也是可以做到的,但它很快就会变得复杂(因此很容易出错),或者过早地阻塞Future.get(),从而消除了异步执行的好处。
另一方面,ReactiveX Observables也比较倾向于,对异步数据流和序列进行组合。

Observables是比较灵活的

ReactiveX观察器,不仅支持单个值的发射(就像Futures一样),还支持值一连串值甚至无限流的发射。Observable是一个单一的抽象,可以用于这些用例中的任何一个。Observable拥有Iterable所有的灵活和优雅。

Observable是异步/推送,而Iterable是同步/拉取

image.png

Observables很少刚愎自用

ReactiveX并不会偏向于某些特定的并发性或异步性来源。Observable可以使用线程池、事件循环、非阻塞I/O、actor(例如来自Akka)或任何适合您的需求、风格来实现。客户端代码将其与Observables的所有交互视为异步的,无论您的底层实现是阻塞的还是非阻塞的,以及您选择如何实现它。

这个Observable是如何实现的?

public Observable getData();

  1. 它和调用者在同一个线程上同步工作吗?
  2. 它在不同的线程上异步工作吗?
  3. 它是否将工作分配给多个线程,这些线程可以按任何顺序向调用方返回数据?
  4. 它使用一个Actor(或多个Actor)而不是线程池吗?
  5. 它是否使用带有事件循环的NIO来进行异步网络访问?
  6. 它是否使用事件循环将工作线程与回调线程分离?

从观察者的角度来看,这并不重要

更重要的是:使用ReactiveX,您以后可以改变主意,从根本上改变Observable实现的基本性质,而不会破坏Observable的消费者。

回调有自己的问题

回调通过不允许任何东西被阻塞来解决Future.get()过早阻塞的问题。它们天生高效,因为它们在响应准备就绪时执行。
但是,与Futures一样,虽然回调很容易与单一级别的异步执行一起使用,但对于嵌套的组合,它们变得很难处理。

ReactiveX是一个多种语言的实现

ReactiveX目前以各种语言实现,以尊重这些语言的习惯用法的方式实现,并且正在快速添加更多的语言。

响应式编程

ReactiveX提供了一组运算符,您可以使用这些运算符筛选、选择、转换、整合和组合Observables。这允许高效的执行和组合。
您可以认为Observable类是通过推送的,类似于Iterable,只不过Iterable是通过拉取的。迭代器是消费者从生产者和线程块中拉取值,直到这些值到达。相比之下,对于Observable,只要有可用的值,生产者就会将值推送给消费者。这种方式更灵活,因为值可以同步或异步到达

示例代码显示了如何将类似的高阶函数应用于Iterable和Observable

Iterable

getDataFromLocalMemory()
  .skip(10)
  .take(5)
  .map({ s -> return s + " transformed" })
  .forEach({ println "next => " + it })

Observable

getDataFromNetwork()
  .skip(10)
  .take(5)
  .map({ s -> return s + " transformed" })
  .subscribe({ println "onNext => " + it })

Observable类型为Four’s Observer pattern模式的Gang添加了两个缺失的语义,以匹配Iterable类型中可用的语义:

  1. 当没有更多可用数据时,生产者向消费者发出完成的信号(在这种情况下,Iterable上的foreach循环完成并正常返回;Observable调用其观察者的onCompleted方法)。
  2. 当发生错误时,生产者向消费者发出错误发生的信号(如果迭代过程中发生错误,则Iterable抛出异常;Observable调用其观察者的onError方法)。

通过这些添加,ReactiveX协调了Iterable和Observable类型。它们之间唯一的区别是数据流动的方向。这一点非常重要,因为现在可以在Iterable上执行的任何操作,也可以在Observable上执行

总结

本文主要介绍了什么是ReactiveX,其中有很多地方说到了Observables,至于Observables具体是什么,会在下一篇文章中单独介绍。
可能有的同学在看完了,本篇文章之后会觉得懵逼。没关系,别着急,因为笔者现在也有同感。笔者会在后面尽量把一些不太好理解的地方搞清楚分享给大家