14

很长一段时间以来,我都在尝试围绕 RX。而且,说实话,我永远不确定我是否得到它 - 或者没有。

今天,我在http://reactive-extensions.github.com/RxJS/上找到了一个解释——在我看来——这太可怕了。它说:

RxJS 之于事件就像 Promise 之于异步。

伟大的。这是一个非常复杂的句子,如果你对 RX 是什么一无所知,那么在这句话之后你就和以前一样愚蠢。

这基本上是我的问题:你在通常的地方找到的关于 RX 的所有解释都让(至少我)觉得很愚蠢。他们将 RX 解释为一个高度复杂的概念,其中包含许多高度复杂的单词和术语等等,我永远不太确定它是关于什么的。

所以我的问题是:你会如何向五岁的人解释 RX?我想要对它是什么、它有什么用处以及它的主要概念有什么清晰、生动的解释?

4

2 回答 2

37

因此,LINQ(在 JavaScript 中,这些是高级数组方法,如map, filter,reduce等 - 如果您不是 C# 开发人员,只要我提到“LINQ”就替换它)为您提供了一堆可以应用的工具序列(粗略意义上的“列表”),用于过滤输入并将其转换为输出(又名“我真正感兴趣的列表”)。但什么是列表?

什么是列表?

一个列表,是一些元素,以特定的顺序。我可以使用 LINQ将任何列表转换为更好的列表。

(不一定是排序顺序,而是顺序)。

事件是一个列表

但是事件呢?让我们订阅一个事件:

OnKeyUp += (o,e) => Console.WriteLine(e.Key)
>>> 'H'
>>> 'e'
>>> 'l'
>>> 'l'
>>> 'o'

嗯。这看起来像一些事情,以特定的顺序。现在你突然意识到,一个列表和一个事件是一回事!

如果列表和事件相同......

...那为什么我不能将输入事件转换和过滤成更有趣的事件这就是 Rx 是什么。它将您所知道的有关处理序列的所有知识,包括所有 LINQ 运算符(如 Select 和 Where 和 Aggregate),并将它们应用于事件。

十分简单。

回调也是一个序列

回调不是基本上只发生一次的事件吗?它基本上不就像一个包含一个项目的列表吗?事实证明是这样,关于 Rx 的一个有趣的事情是,它让我们可以用相同的语言处理事件和回调(以及诸如地理定位请求之类的东西)(即我们可以将两者结合起来,或者等待一个或另一个,等等等等)。

于 2013-02-22T23:10:35.467 回答
16

除了 Paul 的出色回答,我还想添加拉取数据与推送数据的概念。

管道

让我们以一些生成一系列数字并输出结果的代码为例。如果您将其视为一端的流,则您有一个producer正在为您创建新数字的流,而在另一端您有一个consumer正在对这些数字进行操作的流。

拉 - 素数列表

可以说producer正在生成一个素数列表。通常你会有一些函数产生一个数字列表,每次它返回时,它都会通过管道将它计算的下一个值推送到consumer,这会将那个数字输出到屏幕上。

Prime 生成器 ---> Console.WriteLine

在这种情况下,很容易看出producer正在做大部分工作,并且consumer会坐等producer发送下一个值。consumer正在拉动管道,等待producer返回下一个值。

Push - 来自快速进程的进度百分比事件(反应式)

好的,假设您有一个处理 1,000,000 个项目的函数。每个项目需要几毫秒的时间来处理,然后该函数会产生一个百分比值,表示它已经走了多远。如此多的进度值,非常快。

在管道的另一端,您有一个进度条。现在,如果进度条要处理每次更新,UI 将阻止尝试跟上值流。

100 万个项目处理器 ---> 进度条

在这种情况下,数据被推送通过管道,producer然后被阻塞,因为推送consumer了太多数据以使其无法处理。

Reactive 允许您根据您希望consume数据的方式设置延迟、窗口或对管道进行采样。在这种情况下,我会在更新进度条之前每秒对数据进行一次采样。

列表与事件

所以列表和事件有点相同。区别在于数据是通过系统取还是推送。使用列表来提取数据。使用事件推送数据。

于 2013-02-23T02:17:09.203 回答