Rx简介的调度和线程部分指出
SubscribeOn和ObserveOn的使用只能由最终订户调用
它还说,在UI应用程序中,通常是最终订阅者的表示层应该是调用这些方法的层。
我想知道这个建议是否可靠,因为我看到了一些不方便的情况:
- 首先,我不认为表示层应该决定来自数据层的Observable应该订阅到哪里。在我看来,表示层应该不知道数据是来自数据库、RESTneneneba API还是来自内存。因此,数据层可以方便地在返回Observable之前调用
subscribeOn()
,方便地传递IO调度器或即时调度器 - 如果表示层从某个服务或用例获得Observable(反过来又从数据层获得),并且该服务决定需要在某个计算调度器中处理流,那么表示层为什么要关心这一点
- 如果流最初来自UI,那么它需要在UI线程中订阅。然后它将被发送到某个服务来做一些工作,最后返回到表示层,在UI线程中进行观察。这将要求UI流是
subscribeOn()
(UI调度器),然后是observeOn()
(某个其他调度器),最后是observeOn()
(UI调度器。在这种情况下,只能在最终订阅者中调用subscribeOn()
和observeOn()
意味着只能在UI线程中处理流
为什么我应该牺牲应用程序的体系结构,而忽略Rx通过仅由最终订阅者调用这两种方法来轻松切换线程的能力,这有什么好的理由吗?
很高兴看到您已经阅读了这本书,并花时间挑战其中的一些指导。
我给出这个指导的原因是
- 并发性很难,有一个简单的规则可以帮助团队生成更好的代码
- 并发性很难,只有一个地方可以定位您的并发问题,这可以为您的堆栈/分层提供更好的心理模型,并且应该简化测试。在应用程序中引入并发的层越多,情况就越糟
- 阻塞UI线程不是一个好消息。最好尽快退出UI线程,然后尽可能晚地将数据处理延迟回UI。这种模式旨在实现这一目标
这些显然是我的观点,但我已经看到这些简单的指导方针有助于清理数十个项目的代码,减少代码库,提高测试能力,提高可预测性,在许多情况下还可以大幅提高性能。
遗憾的是,很难将这些项目的案例研究放在一起,因为它们中的大多数都受到NDA的保护。
我很想看看它是如何为你工作的,或者你如何应用另一种模式。
-
表示层本身并不关心可观察的内容来自哪里,但它确实关心是否会锁定UI线程。因此,表示层必须采取预防措施来防止这种情况发生。这是一个幸福无知的案例,有一层安全感。
-
表示层不在乎。它只是想确保自己没有被阻止。
-
如果流来自UI并且需要很长时间来处理,则流的所有者应对此负责,并确保它在非UI调度程序上进行处理。然后,如果需要在UI线程中使用,UI必须确保它返回到UI线程。如果处理速度很快,那也没关系。