原文:https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/3.%20Sequences%20of%20coincidence.md
Sequences of coincidence
Rx试图避免管道(pipeline)外的状态,但是,有些事情本质上是有状态的。比如服务器可以启动或关闭,移动设备可以访问wifi,按下按钮。在Rx中,我们将这些视为具有一段持续时间的事件,我们称之为窗口(windows)。在这些窗口内发生的其他事件可能需要区别对待。例如,移动设备将推迟低优先级的网络请求,同时使用更昂贵的通信通道。
Window
使用缓冲区(buffer),我们可以看到一个操作符,它可以根据各种重载,将序列和组值转换为块。窗口运算符与缓冲区具有一对一的关系。主要区别在于它不会以缓冲块的形式返回组。相反,它返回一系列序列,每个序列对应于本来是缓冲区的序列。这意味着每个发出的observable一旦出现在source observable中就会发出它的值,而不是在窗口的末尾发出它们。通过下面的图,可以立即看出缓冲区和窗口之间的关系:
使用window操作后:
如果您还不熟悉缓冲区(buffer),我强烈建议您从此开始。两个运算符中的重载和结果分组是相同的,但缓冲区更容易理解并提供示例。可以使用相同的参数从窗口重载构造每个缓冲区重载:
Window by count
您可以拥有固定数量元素的窗口。一旦窗口发出了所需数量的元素,则observable终止并开始新的元素。
您也可以跳过和重叠窗口像带有window(int count,int skip)的buffer一样。当窗口重叠时,它们将同时发射值,如下一个示例所示。
输出:
我们可以在这里看到内部可观察者同时发射相同的值。为了更清楚地看到每个observable发出的内容,让我们以不同的方式格式化输出:
输出:
通过将内部可观察量转换为列表,我们可以看到相关窗口与缓冲区的关系。
Window by time
您可以拥有固定持续时间的窗口,而不是拥有固定大小的窗口。
您可以构建重叠或跳过元素的windows,就像使用buffer一样
public final Observable> window(long timespan, long timeshift, java.util.concurrent.TimeUnit unit)
输出:
在此示例中,新的window每100ms开始一次,持续250ms。第一个window在0ms时打开并保持打开足够长的时间以捕获[0,1](间隔在100ms时发出第一个值)。每个后续窗口保持打开足够长的时间以捕获接下来的3个值,除非值停止。
Window with signal
最后,您可以使用另一个observable定义window。每当您的信号可观察值发出一个值时,旧窗口关闭,一个新窗口开始。
或者,要具有重叠窗口,您可以提供一个函数,该函数使用信号可观察信号发出的值来构造另一个可以发出窗口关闭信号的observable。当observable终止时,相应的窗口关闭。
这是一个基于信号可观察量的重叠窗口的示例
输出:
此示例与前一示例相同:新window每100ms打开一次,持续250ms,但第一个窗口以100ms而不是0ms开始。但是,我们看到结果有所不同。从时间100ms开始的窗口不会捕获在100ms处发出的值,并且每隔一个窗口都会发生相同的值。发生这种情况是因为窗口开始的间隔事件恰好在作为值的间隔事件之后触发。尽管这两个事件在理论上是同时发生的,但实际上并没有这样的事情。
未完待续!
原文:https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%204%20-%20Concurrency/3.%20Sequences%20of%20coincidence.md
git:https://github.com/woshiyexinjie/rxjava-leaner