冷可观察量的用例是什么?

What is the use case for cold observables?

我理解冷热 Observable 之间的区别,但我总是看到人们使用热 Observable 而不是冷;事实上,如果有人不小心使用了一个冷的 Observable,这会被认为是一个错误,因为它通常是导致不良行为的原因。

在什么情况下您更喜欢或使用冷 Observable 而不是热 Observable?

What's a case where you would prefer or use a cold observable over a hot one?

我希望我说的不是显而易见的,而是任何您想从可观察对象的 all 值(或通过过滤完整集得到的某些子集)访问的情况历史。

我想到的第一个例子是对学生的 所有 考试成绩进行平均,而不仅仅是您订阅后得到的分数。

首先,我邀请您复习,以确保您对冷热有一个透彻的了解。

Cold observables 允许生产者懒惰,这是一个非常理想的特性。在没有使用这些价值(没有消费者)的情况下产生价值(生产可能很昂贵)是一种浪费。因为这样的冷可观察量是构建块......更经常地从中导出热可观察量。

因此,冷 observables 最常见的用例是懒惰地派生热 observables。如果您考虑一下,您需要以某种方式以编程方式构建这些热可观察量。一种方法是使用主题(然后您就是制作人)。另一种方法是通过运算符从其他预先存在的 observables 派生它们,预先存在的 observables 也从其他人派生等等。在链的末尾,你应该找到 Rx.Observable.create,这是一个冷 observable。

当你需要惰性时(只有当有消费者时才开始产生值,或者控制生产过程的开始),你可以使用冷观察。例如,defer 允许您仅在有消费者时启动生产者。例如,当您有一个热门的可观察对象但您还没有准备好收听它时,可以使用它。

当您需要重现一个产生价值的过程时,您还需要冷可观察对象(每个新订阅者都将重新启动完全相同的过程)。例如,出于测试目的,您希望使用完全相同的序列多次,但在不同的时间使用不同的消费者。

最后,这个问题听起来更像是一个哲学问题。您有两种工具可供使用,重要的是了解您需要什么、您拥有什么以及适合您的用例。

答案的核心在于 Ben Lesh 的简洁摘要:

TL;DR: You want a HOT observable when you don’t want to create your producer over and over again.

在直接回答问题 "What's a case where you would prefer or use a cold observable over a hot one?" 时,我将提供一般答案和具体示例。

通常,使用冷可观察对象来模拟每次需要时创建的流比创建热可观察对象并尝试对其进行处理要方便得多。

具体来说,请考虑以下简单示例。假设你想通过从 10 开始倒计时来响应按钮上的点击。如果在倒计时期间再次单击按钮,它将再次从 10 开始。如果 click$ 对按钮事件建模,你可能会有这样的事情:

const subscription = click$
  .flatMapLatest(_ => Rx.Observable.interval(1000).take(10))
  .select(x => 10 - x)
  .subscribe(x => console.log('clicked: ' + x));

考虑一下在没有冷可观察量的情况下如何建模。你会如何:

  1. 提前初始化流以便在需要时提供适当的值?
  2. 避免处理间隔滴答和订阅时间之间的秒数?
  3. 处理可以从任何数字开始而不仅仅是 1 的序数?
  4. 管理流的清理逻辑?

1 和 3 很容易解决,但 2 和 4 很麻烦。

在回答你的第二个问题时 "Is it laziness?" 我认为它不是。一个冷的 observable 可以离开它直到订阅产生它的值的那一刻。一个热的 Observable 可以离开它直到订阅挂钩适当的事件。他们都以自己的方式懒惰(或者至少可以如此)。关键区别在于 Ben Lesh 所说的:你想每次都创建一个制作人吗?有时,你真的会。