原文:https://github.com/Froussios/Intro-To-RxJava/blob/master/Part 4 - Concurrency/3. Sequences of coincidence.md
join允许您将两个序列中的项组合在一起。我们已经看过zip,它根据index对值进行配对。join允许您根据时间配对值。让我们先看一下方法签名:
join合并两个序列,称为“left(左)”和“right(右)”。该方法不是静态(static)的,在方法签名中,我们可以看到两个名为leftDurationSelector和rightDurationSelector的方法,它们将相应序列的项作为参数。它们返回一个定义持续时间(即window)的observable。这些window用于选择要配对的值。配对的值将传递给resultSelector函数,该函数将它们组合成单个值,就像zip中的resultSelector一样,该值将由join发出。
这使join变得强大,但也很难理解的是,如何选择值进行配对。到达序列中的每个值都会为自己开一个window。相应的持续时间选择器决定每个值的window何时终止。当window打开时,以相反顺序到达的任何值都将与它配对。这个过程对于左右序列是对称的,所以让我们考虑一个只有一个序列的项目有window的情况。
在第一个示例中,left序列中的窗口从不关闭,而右序列中的window为0。
输出:
当左值的窗口永远不会结束时,这意味着左序列中的每个值都将与从右序列后面的每个值配对。因为这里右侧序列的频率是左侧序列的一半,在两个右侧值之间,左侧还有两个窗口打开。第一个右边的值与前两个左边的值配对,第二个右边的值与前四个左边的值配对,第三个右边的值与第六配对,依此类推。
让我们改变一下这个例子,看看当每隔100毫秒左右发射并且150毫秒后左窗关闭时会发生什么。然后会发生的是每个左窗口保持打开足够长的时间以捕获两个正确的值:一个是同时发出的,另一个是在100ms后发出的。
输出:
两个序列都有窗口。序列的每个值都去匹配:
- 如果旧值的窗口仍然打开,则相反序列的任何旧值
- 如果此值的窗口仍处于打开状态,则相反序列的任何较新值
groupJoin
一旦检测到一对,join就会将两个值传递给结果选择器并发出结果。groupJoin更进了一步。让我们从方法签名开始吧。
签名与resultSelector与join类似,除了resultSelector,结果(result)选择器从左侧序列中获取一个项目,从右侧序列中获取一个值的可观察值。该可观察量将发出左值与之配对的每个正确值。groupJoin中的配对是对称的,就像连接一样。
让我们从连接中重新审视我们的例子,左边的窗口永远不会关闭。
输出:
在结果选择器中,我们有一个左值和一个可观察的右值。我们使用它来打印右侧与左侧值配对的所有值。如果您回到使用连接的示例,您将看到对是相同的,更改如何在resultSelector中提供给我们。
您可以使用groupJoin和flatMap实现join
您还可以使用join和groupBy实现groupJoin。这样做会要求您构造元组(tuples)作为结果,并在元组的左侧部分执行groupBy。
原文:https://github.com/Froussios/Intro-To-RxJava/blob/master/Part 4 - Concurrency/3. Sequences of coincidence.md
git:https://github.com/woshiyexinjie/rxjava-leaner