subscribeOn 和 observeOn 应该只由最终订阅者调用吗?
Should subscribeOn and observeOn only be invoked by the final subscriber?
Rx 简介 的 Scheduling and Threading 部分说
the use of SubscribeOn and ObserveOn should only be invoked by the final subscriber
它还表示,在 UI 应用程序中,表示层(通常是最终订阅者)应该是调用这些方法的层。
我想知道这个建议是否可靠,因为我看到有些情况下这样做并不方便:
- 首先,我认为表示层不应该决定应该在何处订阅来自数据层的 Observable。在我看来,表示层应该不知道数据是来自数据库、来自 REST API 还是来自内存。为此,数据层在返回Observable前调用
subscribeOn()
比较方便,传递IO Scheduler或者直接的Scheduler是方便的。
- 如果表示层从某个服务或用例中获取 Observable(后者又从数据层获取)并且此服务决定它需要在某个计算调度程序中处理流,那么表示层为什么要处理关心这个?
- 最初来自 UI 的流怎么办,因此需要在 UI 线程中订阅它。然后它会被发送到一些服务做一些工作,最后回到表现层在UI线程中观察。这将需要 UI 流成为
subscribeOn()
UI 调度程序,然后 observeOn()
其他调度程序,最后 observeOn()
UI 调度程序。在这种情况下,只能在最终订阅者中调用 subscribeOn()
和 observeOn()
意味着流只能在 UI 线程中处理。
为什么我应该牺牲我的应用程序的体系结构并忽略 Rx 通过仅由最终订阅者调用这两个方法来轻松切换线程的能力?
表示层本身并不关心可观察对象来自何处,但它确实关心它是否可能锁定 UI 线程。因此表示层必须采取预防措施来防止这种情况发生。这是一个带有安全层的幸福无知的案例。
表示层不关心。它只是想确保它自己没有被阻止。
如果流来自 UI 和 则需要很长时间来处理流的所有者 应该 认真对待这一点,并确保它在 non-UI 调度程序上进行处理。然后 UI 必须确保它返回到 UI 线程,如果它需要在那里被消耗的话。如果处理速度快就无所谓了。
很高兴看到您已阅读本书并花时间挑战其中的一些指导。
我给出这个指导的原因是因为
- 并发很难,有一个简单的规则可以帮助 团队 产生更好的代码
- 并发很难,有一个地方来定位您的并发问题可以让您的 stack/layering 有更好的心智模型,并且应该可以简化测试。在你的应用程序中引入并发的层越多,越糟糕
- 阻塞 UI 线程可不是什么好消息。尽快离开 UI-Thread,然后尽可能晚地延迟返回 UI 的任何数据处理是可取的。此模式旨在实现该目标。
这些显然是我的意见,但我已经看到这些简单的指南有助于清理数十个项目的代码、减少代码库、提高测试能力、提高可预测性并在许多情况下显着提高性能。
遗憾的是,很难将这些项目的案例研究放在一起,因为它们中的大多数都受到 NDA 的保护。
我很想知道它如何为您工作或您如何应用替代模式。
Rx 简介 的 Scheduling and Threading 部分说
the use of SubscribeOn and ObserveOn should only be invoked by the final subscriber
它还表示,在 UI 应用程序中,表示层(通常是最终订阅者)应该是调用这些方法的层。
我想知道这个建议是否可靠,因为我看到有些情况下这样做并不方便:
- 首先,我认为表示层不应该决定应该在何处订阅来自数据层的 Observable。在我看来,表示层应该不知道数据是来自数据库、来自 REST API 还是来自内存。为此,数据层在返回Observable前调用
subscribeOn()
比较方便,传递IO Scheduler或者直接的Scheduler是方便的。 - 如果表示层从某个服务或用例中获取 Observable(后者又从数据层获取)并且此服务决定它需要在某个计算调度程序中处理流,那么表示层为什么要处理关心这个?
- 最初来自 UI 的流怎么办,因此需要在 UI 线程中订阅它。然后它会被发送到一些服务做一些工作,最后回到表现层在UI线程中观察。这将需要 UI 流成为
subscribeOn()
UI 调度程序,然后observeOn()
其他调度程序,最后observeOn()
UI 调度程序。在这种情况下,只能在最终订阅者中调用subscribeOn()
和observeOn()
意味着流只能在 UI 线程中处理。
为什么我应该牺牲我的应用程序的体系结构并忽略 Rx 通过仅由最终订阅者调用这两个方法来轻松切换线程的能力?
表示层本身并不关心可观察对象来自何处,但它确实关心它是否可能锁定 UI 线程。因此表示层必须采取预防措施来防止这种情况发生。这是一个带有安全层的幸福无知的案例。
表示层不关心。它只是想确保它自己没有被阻止。
如果流来自 UI 和 则需要很长时间来处理流的所有者 应该 认真对待这一点,并确保它在 non-UI 调度程序上进行处理。然后 UI 必须确保它返回到 UI 线程,如果它需要在那里被消耗的话。如果处理速度快就无所谓了。
很高兴看到您已阅读本书并花时间挑战其中的一些指导。
我给出这个指导的原因是因为
- 并发很难,有一个简单的规则可以帮助 团队 产生更好的代码
- 并发很难,有一个地方来定位您的并发问题可以让您的 stack/layering 有更好的心智模型,并且应该可以简化测试。在你的应用程序中引入并发的层越多,越糟糕
- 阻塞 UI 线程可不是什么好消息。尽快离开 UI-Thread,然后尽可能晚地延迟返回 UI 的任何数据处理是可取的。此模式旨在实现该目标。
这些显然是我的意见,但我已经看到这些简单的指南有助于清理数十个项目的代码、减少代码库、提高测试能力、提高可预测性并在许多情况下显着提高性能。
遗憾的是,很难将这些项目的案例研究放在一起,因为它们中的大多数都受到 NDA 的保护。
我很想知道它如何为您工作或您如何应用替代模式。