RxJava - 何时以及为何使用Observable.share()

时间:2018-01-26 11:33:06

标签: android rx-java reactive-programming rx-java2

我见过这样的照片:

Observable<String> nameChanges = nameDataSource.changes().share();

// One subscriber
autoUnsubscribe(nameChanges.subscribe(() -> { ... }));

// Another subscriber
autoUnsubscribe(nameChanges.map(...).filter(...).subscribe(...));

// autoUnsubscribe is called when the UI is torn down

我的问题是:

为什么每当我想在多个地方收听Observable时都需要调用share()?

为什么share()不是所有observable的默认行为?

如果上面的代码即使没有.share()也能正常工作,那就太好了。我不需要考虑何时需要分享一个Observable,当我不需要时。

是否出于性能原因,因为拥有一个订户是一个可以更有效处理的特殊情况?

从文档中我不清楚:

  

share()返回一个新的ObservableSource,它可以多播(共享)原始的ObservableSource。只要至少有一个Observer,ObservableSource就会订阅并发送数据。

enter image description here

2 个答案:

答案 0 :(得分:14)

Observable有两种:冷和热。 Observable在有Observer的情况下开始生产项目,并且他们会单独执行。订阅多个Observer将导致多次运行相同的冷Observable。例如,Observable发出网络请求。

相比之下, Observable可以生成有或没有Observer s的项目。这些Observable通常会将相同的项目组播到其当前Observer的所有内容中。例如,Observable按钮点击次数。

要将感冒Observable变为热门感冒,您可以使用publish(),这样可以确保只有一个订阅设置到源Observable,无论多少Observer有的。因此,该链现在将从Observable s的角度充当热门多播Observer

但是,Observable Observer {{}}} publish()已经消失后,保持原本冷refCount()运行通常是不经济的,因此可以使用share()运算符当没有有趣的派对时,要跟踪它们并停止来源。

如果您的来源已经很热,则不需要Observable

  

为什么不将share()作为所有observable的默认行为?

实际上,这个属性是现代反应式编程范式的重要贡献之一:冷热Observer的区别。

然而,多播本身很昂贵,因为你必须跟踪当前Observable的集合,以便通过新事件通知他们,这可以导致各种逻辑竞争条件得到保护反对。已知感冒Observer仅与单个function vitahc_excerpt_in_product_archives() { the_excerpt(); } add_action('woocommerce_after_shop_loop_item_title','vitahc_excerpt_in_product_archives', 10); 通话,因此无需额外的跟踪开销。

答案 1 :(得分:1)

I would not have to think about when I need to share an Observable, and when I don't.我担心在编程时你必须要考虑。 ;)

在上面的代码中,是的,分享是有道理的。但是,如果我们在后端更新某些内容,使用来自两个不同点的相同网络和方法调用,使用不同的数据进行更新,该怎么办?您将使用相同的Observable进行相同的调用,但您肯定不希望共享Observable实例(以及网络调用),因为这意味着所有带有数据的连续调用都将被丢弃赞成第一个。或者,如果您想在订阅时启动计时器,您再次不希望与其他Observable共享此计时器。

此外,添加某些行为比删除更容易。例如,如果共享是默认值,而第二个订阅者不想共享和删除共享 - 那么第三个用户呢?它会与第一个分享吗?此时,共享属性成为Subscriber而不是Observable的属性,您将无法清楚地知道哪一个是共享的,哪一个不是。