官方文档链接:http://reactivex.io/documentation/observable.html
1.前言
ReactiveX的概念是,一个观察者订阅一个被观察者,然后观察者响应被观察者产生/传递的每一个事件或事件队列。这种模式有利于并发操作,当等待被观察者产生/传递事件时,不需要阻塞线程,而是创建观察者,随时准备响应被观察者将来时间做出的事情。
这节介绍什么是响应模式,什么是观察者和被观察者(以及观察者如何订阅被观察者)。以后将介绍如何使用各种被观察者的操作符来连接被观察者和改变他们行为。文档附带解释用的图表,下面示例反映图表如何展示被观察者和它的转换:
2.被观察者
可以理解为数据源,内部封装了一系列事件等待自己来调用,从而传递出去(产生事件)。
参考的文章:
- Single — 只产生一个事件的特定版本的被观察者
- Rx Workshop: Introduction
- Introduction to Rx: IObservable
- Mastering observables (来自Couchbase的文档)
- 2 minute introduction to Rx by Andre Staltz (“假设被观察者是异步的不可变的数组”)
- Introducing the Observable by Jafar Husain (JavaScript视频教程)
- Observable object (RxJS) by Dennis Stoyanov
- Turning a callback into an Rx Observable by @afterecho
3.异步处理
在许多软件开发任务中,或多或少期望,编写的指令按照书写顺序,依次执行,逐步完成。但在ReactiveX中,许多指令可以并行执行,并由观察者按任意顺序捕获相应结果。与方法调用相比,先定义被观察者,然后用观察者订阅的模式来检索和转换数据,随时准备着在某个时间点捕获和响应事件的发生。这种方式有一个好处,当有一堆互不依赖的任务时,让它们同时开始比等待上一个结束再开始下一个要好,因为所有任务完成消耗的时间只由耗时最长的任务决定。
有不少术语来描述这种异步编程和设计的模型,本文将采用:观察者订阅被观察者。被观察者通过调用观察者的方法来传递事件和发送通知给自己的观察者。在后面的文章中,有时会称呼“观察者”为“订阅者”、“监视者”、“响应者”,这种模型通常也被称为“响应模式”。
4.创建观察者
下面的例子将使用类似Groovy的伪代码,因为ReactiveX在多种语言下都有实现。
普通方法调用——不是那种异步的、ReactiveX中典型的并行调用——流程就像这样:
- 调用一个方法。
- 一个变量存储那个方法返回的值。
- 用那个变量和它的新值做一些有意义的事。
// make the call, assign its return value to `returnVal`
returnVal = someMethod(itsParameters);
// do something useful with returnVal
在异步模型中,流程更像这样:
- 定义一个方法,使用异步调用返回的值做一些有意义的事;这个方法是观察者的一部分。
- 定义异步调用本身作为被观察者。
- 通过观察者订阅被观察者来关联两者(这一步引发被观察者产生事件)。
- 继续业务逻辑;每当调用返回时,观察者方法将开始对返回的值(被观察者产生的事件)执行操作。
// defines, but does not invoke, the Subscriber's onNext handler
// (in this example, the observer is very simple and has only an onNext handler)
def myOnNext = { it -> do something useful with it };
// defines, but does not invoke, the Observable
def myObservable = someObservable(itsParameters);
// subscribes the Subscriber to the Observable, and invokes the Observable
myObservable.subscribe(myOnNext);
// go on about my business
4.1.观察的事件
若观察者要通过subscribe()
方法与被观察者连接起来,需实现下面方法的一些子集:
onNext()
每当被观察者产生一个事件,它将调用这个方法,并使用它产生的事件作为参数。
onError()
被观察者调用这个方法,表明它未能生成预期的数据,或者遇到一些其它的错误,将不会接着调用onNext()
或onCompleted()
方法。onError()
方法使用导致错误的指示,作为它的参数。
onCompleted()
被观察者调用onNext()
方法之后,且没有遇到任何问题,当结束事件的产生时,它调用这个方法。
被观察者可能调用onNext()
方法零次或多次,之后可能调用onCompleted()
或onError()
方法中的一种,作为最终调用。这里约定一下,文章中调用onNext()
方法称为“产生事件”,而调用onCompleted()
或onError()
方法称为“发送通知”。
def myOnNext = { item -> /* do something useful with item */ };
def myError = { throwable -> /* react sensibly to a failed call */ };
def myComplete = { /* clean up after the final response */ };
def myObservable = someMethod(itsParameters);
myObservable.subscribe(myOnNext, myError, myComplete);
// go on about my business
可以参考这篇文章 Introduction to Rx: IObserver
4.2.取消订阅
有一些ReactiveX的实现,定义了专门的观察者,即订阅者,实现了取消订阅的方法。调用这个方法表明,订阅者不再关心当前订阅的任何一个被观察者。那些被观察者(如果它们没有被其它观察者订阅)之后可以选择停止产生新的事件。取消订阅的结果,将会回溯观察者订阅被观察者时使用的操作链,并且将导致链中的每个节点停止传递事件(封装在被观察者对象中)。但这个过程不能保证立即发生,被观察者有可能产生并尝试传递事件,即使没有观察者再订阅它,仍能持续一段时间。
4.3.命名规则
每种特定语言对ReactiveX的实现,有许多共同点,但没有规范的命名标准。因为它们都有自己的命名习惯,而且这些名字在不同的上下文中有不同的含义,或者不符合特定实现语言的习惯。
5.被观察者类型
由被观察者的类型,决定什么时候产生它自己的事件队列。热类型,在它被创建时会开始产生事件,之后任何观察者再订阅它,可能从队列中间的某处开始捕获。冷类型,则相反,等到有观察者订阅它才开始产生事件,所以能保证观察者从开始捕获整个队列。
在ReactiveX的一些实现中,有一些被称为可连接的被观察者。这样的被观察者不会开始产生事件直到它的connect()
方法被调用,不管是否有观察者已经订阅它。
6.总结
理解被观察者和观察者,不过才刚刚接触ReactiveX的概念。它们本身只能算是对标准观察者模式(若有不清楚此模式的,后期会在设计模式文集中加以说明)轻微的扩展,以便适合处理一系列事件。
ReactiveX真正的核心,是通过操作符改变、组合和控制被观察者产生的事件队列。尤其允许将异步事件的队列组合在一个声明中,保留回调所有的优点,但没有回调嵌套处理的缺点。下一节将详细给大家讲解这些神奇的操作符。