当前位置: 首页 > 知识库问答 >
问题:

subscribeOn和observeOn是否应仅由最终订阅者调用?

南宫才英
2023-03-14

Rx简介的调度和线程部分说

订阅和观察的使用只能由最终订阅者调用

它还说,在UI应用程序中,通常是最终订阅者的表示层应该是调用这些方法的层。

我想知道这个建议是否可靠,因为我看到有些情况下这样做并不方便:

  1. 首先,我不认为表示层应该决定来自数据层的可观察对象应该在哪里订阅。在我看来,表示层应该不知道数据是来自数据库、REST API还是内存。出于这个原因,数据层在返回可观察对象之前调用subbeOn()很方便,传递IO调度程序或即时调度程序也很方便。
  2. 如果表示层从某个服务或用例(反过来又从数据层获取它)中获取可观察的,并且这个服务决定它需要在某个计算调度程序中处理流,为什么表示层要关心这个?
  3. 最初来自UI的流怎么样,所以它需要在UI线程中订阅。然后它将被发送到某个服务来做一些工作,最后返回到表示层以在UI线程中观察。这将要求UI流是订阅()UI Scheduler,然后是观察()其他一些Scheduler,最后是观察()UI Scheduler。在这种情况下,仅在最终订阅者中能够调用订阅()观察()意味着只能在UI线程中处理流。

有没有什么好的理由让我牺牲应用程序的架构,而忽略Rx通过仅由最终订阅者调用这两种方法来轻松切换线程的能力?

共有2个答案

杜鸿彩
2023-03-14

>

  • 表示层本身并不关心可观察对象来自哪里,但它确实关心它是否会锁定UI线程。因此表示层必须采取预防措施来防止这种情况发生。这是一个带有安全层的幸福无知的例子。

    表示层不关心。它只想确保自己没有被阻止。

    如果流来自UI并且需要很长时间来处理,那么流的所有者应该对此负责,并确保它是在非UI调度程序上处理的。然后UI必须确保它返回到UI线程(如果需要在那里使用)。如果处理速度快,那也没关系。

  • 龙永思
    2023-03-14

    很高兴看到你已经读了这本书,并且正在花时间挑战那里的一些指导。

    我给出这个指导的原因是

    1. 并发很难,拥有简单的规则有助于团队生成更好的代码
    2. 并发很难,只有一个位置来定位您的并发问题可以为您的堆栈/分层提供更好的心理模型,并且应该简化测试。在您的应用程序中引入并发的层越多,情况就越糟
    3. 阻止UI线程不是好消息。尽快关闭UI-Thread,然后尽可能晚地延迟UI上的任何数据处理是可取的。这种模式旨在服务于这个目标。

    这些显然是我的观点,但我已经看到这些简单的指导原则有助于清理数十个项目上的代码,减少代码库,提高测试能力,提高可预测性,并在许多情况下大幅提高性能。

    遗憾的是,很难将这些项目的案例研究放在一起,因为大多数项目都受到NDA的保护。

    我很想看看它是如何为你工作的,或者你是如何应用另一种模式的。

     类似资料:
    • 我们学到了如何在一个调度器上运行一个任务。但是我们如何利用它来和Observables一起工作呢?RxJava提供了subscribeOn()方法来用于每个Observable对象。subscribeOn()方法用Scheduler来作为参数并在这个Scheduler上执行Observable调用。 在“真实世界”这个例子中,我们调整loadList()函数。首先,我们需要一个新的getApps(

    • 我读到过,通常您不必明确地取消对或的订阅,因为: ActivatedRoute及其可观察到的内容与路由器本身绝缘。当不再需要路由组件时,路由器会销毁该组件,并且注入的ActivatedRoute也会随之死亡。 每当有人导航到另一个组件/页面时,就会被再次订阅。只有当事件是的实例时,我才必须在路由器订阅中执行此操作,因为在此之前,url参数还不可用。 我的问题是,那些订阅会发生什么?他们是自动退订还

    • 问题内容: 我只是在学习Rx-java和Rxandroid2,我只是对SubscribeOn和ObserveOn之间的主要区别感到困惑。 问题答案: SubscribeOn指定将在其上运行Observable的调度程序。ObserveOn指定调度程序,观察者将在该调度程序上观察此Observable。 因此基本上,SubscribeOn主要是在后台线程上预订(执行)(您不想在等待可观察对象时阻塞U

    • 我只是在学习Rx-java和Rxandroid2,我只是很困惑SubscribeOn和AnalyeOn之间的主要区别是什么。

    • 这只是为了澄清发布/订阅线程。 我的疑问是在正常的发布者/订阅者模式中,订阅者和发布者是在同一个线程上运行还是在不同的线程中运行? 还是取决于实现? 到目前为止,我所想的是不同的订阅会有自己的线程,而publisher在其上运行的是自己的线程?

    • 我正在尝试破译以下函数: null