Java文档说出以下内容:
仅当发布者为该特定的最后一个值提供的时间窗口内没有发出新值时,才发出此Flux中的最后一个值。
但是我发现上面的描述令人困惑。我在gitter聊天中读到它类似于RxJava中的debounce。有人可以用一个例子来说明吗?在彻底搜索后,我无法在任何地方找到它。
答案 0 :(得分:0)
sampleTimeout
可让您将随播广告Flux
X'
与来源中的每个传入值x
相关联。如果X'
在源中发出下一个值之前完成,则会发出值x
。如果不是,则x
被删除。
对后续值应用相同的处理。
将其视为将原始序列拆分为由每个伴随通量的开始和完成分隔的窗口。如果两个窗口重叠,则触发第一个窗口的值将被删除。
另一方面,你有sample(Duration)
只涉及单个伴侣Flux。它将序列分成连续的窗口,在常规时间段内,并且除了在特定窗口期间发出的最后一个元素外,它们都会丢弃。
(编辑):关于您的用例
如果我理解正确,您似乎需要定期安排不同长度的处理,但您也不想考虑处理时间超过一个期间的值
如果是这样,听起来你想要1)使用publishOn
在自己的线程中隔离你的处理,2)只需要sample(Duration)
来满足需求的第二部分(延迟分配给一个任务没有改变。)
这样的事情:
List<Long> passed =
//regular scheduling:
Flux.interval(Duration.ofMillis(200))
//this is only to show that processing is indeed started regularly
.elapsed()
//this is to isolate the blocking processing
.publishOn(Schedulers.elastic())
//blocking processing itself
.map(tuple -> {
long l = tuple.getT2();
int sleep = l % 2 == 0 || l % 5 == 0 ? 100 : 210;
System.out.println(tuple.getT1() + "ms later - " + tuple.getT2() + ": sleeping for " + sleep + "ms");
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
return l;
})
//this is where we say "drop if too long"
.sample(Duration.ofMillis(200))
//the rest is to make it finite and print the processed values that passed
.take(10)
.collectList()
.block();
System.out.println(passed);
哪个输出:
205ms later - 0: sleeping for 100ms
201ms later - 1: sleeping for 210ms
200ms later - 2: sleeping for 100ms
199ms later - 3: sleeping for 210ms
201ms later - 4: sleeping for 100ms
200ms later - 5: sleeping for 100ms
201ms later - 6: sleeping for 100ms
196ms later - 7: sleeping for 210ms
204ms later - 8: sleeping for 100ms
198ms later - 9: sleeping for 210ms
201ms later - 10: sleeping for 100ms
196ms later - 11: sleeping for 210ms
200ms later - 12: sleeping for 100ms
202ms later - 13: sleeping for 210ms
202ms later - 14: sleeping for 100ms
200ms later - 15: sleeping for 100ms
[0, 2, 4, 5, 6, 8, 10, 12, 14, 15]
因此阻塞处理大约每200ms触发一次,并且只保留在200ms内处理的值。