观察者和订阅者之间有什么区别?

时间:2014-12-27 04:03:21

标签: java rx-java

我正在尝试破译以下功能:

Subscription getCar(id, Observer<Car> observer) {
    return getCarDetails(id, new Observer<CarDetails> {
                             @Override
                             onNext(CarDetails details) {           
                                 observer.onNext(details.getCar());
                             } });
}

我从http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/得到了一个很好的rxjava介绍,但是它只提到了Observer,说你大部分时间都在使用Subscriber消费者从Observable发出的消息。

有人可以向我解释

  1. 什么是观察者?
  2. 观察者与订阅者有何不同?
  3. 上面的代码段是做什么用的?
  4. Javadoc让它看起来像订阅者。订阅者的javadoc说它实现了观察者和订阅。我很困惑。

4 个答案:

答案 0 :(得分:59)

已编辑:使用@ Alrid的评论

<强> TL;博士

public abstract class Subscriber<T> implements Observer<T>, Subscription

所以SubscriberObserver的一个实现,在订阅时有额外的语义(它更多的是关于取消订阅)。 您的问题中的代码只显示它传递{​​{1}}接口,而不是实现(通常的编程实践)。

此代码也返回Observer,这可能是因为此代码的作者认为客户端应该只能访问Subscription方法,而无法访问observable生成的元素。这可能是程序员错误。

长篇故事

您真的应该阅读本网站(或书籍)的内容:http://www.introtorx.com 它与Rx.Net有关,但概念完全相同,它们是由Erik Meijer创建的,RxJava实现者遵循them(如果适用于Java语言)。

此页面将引起您的兴趣(这是第二章):KeyTypes

在这里,您将阅读第一段:

  

使用Rx时有两种关键类型需要理解,辅助类型的子集可以帮助您更有效地学习Rx。 IObserver和IObservable构成了Rx的基本构建块,而ISubject的实现减少了Rx新手的学习曲线。

...

  

本质上,Rx建立在Observer模式的基础之上。 .NET已经公开了实现Observer模式的其他一些方法,例如多播委托或事件(通常是多播委托)。

即使类型/ API略有不同,您也会在本书中学到很多东西,可能比一些博客更多。

这本没有说 ......因为它在RxJava实现中

此时RxJava主要开发人员引入了一个略微变化(参见PR #792),允许区分两种类型的合同:

  • 通知 - &gt; Subscription
  • (联合国)订阅 - &gt; Observer

此更改允许更好地表达/拆分RxJava库的实现类的这些问题。

但是作为库用户,使用RxJava库的实际实现应该足够好了。

实现订阅者需要更多的知识,工作和关注,实际上订阅语义非常重要,具体取决于源可观察的类型(热或冷?创建昂贵?)


在上述情况下公开Subscription而不是Subscriber在大多数情况下不会干扰代码,但除非需要那些非订阅语义,否则它不是它的预期用途。但最终实施Observer,并可能涉及陷入一些陷阱,如:

  1. 将资源用于您不会使用的功能
  2. 无法继承其他类
  3. 编写错误的取消订阅代码
  4. 复制/粘贴代码不正确的代码或为不同的上下文编写的正确代码

答案 1 :(得分:35)

(编辑:这显然只适用于RxJava 1。)

  1. Observer是一个可以从数据源(Observable)获取数据的对象。数据源通过调用观察者的onNext()

  2. 将数据推送到它
  3. SubscriberObserver,也可以取消订阅该数据源(通过Subscription界面)。

  4. getCar()函数试图返回汽车,但没有直接的方法可以做到这一点。但是有一个功能可以获取汽车详细信息(getCarDetails()),这将调用观察者的所有汽车详细信息。因此它调用该函数并向其传递一个观察者,当它获取数据时,将从细节中获取汽车数据并将其传递给自己的观察者。

答案 2 :(得分:17)

在RxJava 2中 org.reactivestreams.Subscriber是一个符合Reactive Streams specification的界面。

Observable的主要区别在于新Subscriber支持背压。

Observer已被子标记为Observable,而Subscriber已订阅Flowable(已实施org.reactivestreams.Publisher)。

查看详细说明here

答案 3 :(得分:3)

同样在 RxJava2 中,如果您希望能够取消订阅,则应ResourceObserver使用ObservableResourceSubscriber使用Flowable

选中此question