首页 文章

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

提问于
浏览
4

我见过这样的照片:

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 . 只要至少有一个观察者,这个ObservableSource就会被订阅并发出数据 .

enter image description here

2 回答

  • 10

    有两种 Observable :冷和热 . Cold Observable 在他们有 Observer 时开始 生产环境 物品并且他们是单独进行的 . 订阅多个 Observer 将导致多次运行相同的冷 Observable . 一个例子是发出网络请求的 Observable .

    相比之下, hot Observable 可以生成有或没有 Observer s的项目 . 这些 Observable 通常将相同的项目组播到它们当前的所有 Observer . 一个例子是 Observable 按钮点击 .

    要将冷却 Observable 变为热门,您可以使用 publish() ,这将确保只有一个订阅 Build 到源 Observable ,无论有多少 Observer . 因此,该链现在将从 Observer '的角度充当热门多播 Observable .

    然而,在 publish() 已经消失之后,保持原本冷却运行通常是不经济的,因此 refCount() 运算符可用于跟踪它们并在没有任何有趣的方时停止源 .

    如果您的来源已经很热,那么您不需要 share() .

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

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

    但是,多播本身就很昂贵,因为你必须跟踪当前的集合,以便通过新事件通知它们,这可以导致各种逻辑竞争条件得到防御 . 已知冷 Observable 仅与单个 Observer 通话,因此不需要额外的跟踪开销 .

  • 1

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

    在上面的代码中,是的,共享是有道理的 . 但是,如果我们在后端更新某些内容,使用来自两个不同点的相同网络和方法调用,使用不同的数据进行更新,该怎么办?您将使用相同的Observable进行相同的调用,但您当然不希望共享Observable实例(以及网络调用),因为这意味着所有带有数据的连续调用都将被丢弃而有利于第一个调用 . 或者,如果你想在每个're subscribed, you again wouldn'想要与其他Observables分享时启动一个计时器 .

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

相关问题