Java 项目反应器-如何按窗口处理结果
我有以下建议:Java 项目反应器-如何按窗口处理结果,java,spring,reactive-programming,project-reactor,Java,Spring,Reactive Programming,Project Reactor,我有以下建议: Flux.range(0, 100) .log("before window") .window(10) .map(Flux::toList) .log("after window") .map((w) -> { System.out.println(w.subscribe().get())); return 1; }) .reduce(0, (a, b) -> a + b)
Flux.range(0, 100)
.log("before window")
.window(10)
.map(Flux::toList)
.log("after window")
.map((w) -> {
System.out.println(w.subscribe().get()));
return 1;
})
.reduce(0, (a, b) -> a + b)
.doOnSuccess(System.out::println)
.subscribe();
我想在doOnNext
中,我现在应该可以得到一块物品。但是,.get
总是失败,单块读取时出现超时
执行
我从日志中看到,所有在.window
之前都已处理,结果日志给出:
[ main] before window : onNext(0)
[ main] after window : onNext({ operator : "BufferAll" })
官方文档中没有那么多信息,所以我想我误解了什么,并且错误地使用了窗口功能。但我到底做错了什么
更新
我发现如果改用.doOnSuccess
可以避免这个特殊问题。比如:
.map((w) -> {
w.doOnSuccess((w2) -> System.out.println(w2))).subscribe();
return 1;
}
但真正的问题是,在我的情况下,我需要根据提供的数据返回一个数字(而不是1
)。我可以在这里创建一个新的Mono
,但无论如何,以后我应该。获取它。例如,在final.reduce
中。因此,如果我执行.reduce(0,(a,b)->a+b.get())
它将在那里失败
如何安全地从Mono中获取价值
更新2
现在我已经删除了Flux:toList并自己做,在窗口之后从映射阶段返回Mono
。这可能就是它应该的样子
.window(10)
.log("after window")
.map((w) -> {
//basically i'm reducing Flux to a Mono<List> and return number of a [good] elements in it
return w.reduce(...).map(ids -> 100).subscribe();
})
.reduce(0, (a, b) -> a + b.get())
.window(10)
.log(“窗口后”)
.map((w)->{
//基本上,我将通量减少到一个单声道,并返回其中一个[好]元素的数量
返回w.reduce(…).map(id->100.subscribe();
})
.reduce(0,(a,b)->a+b.get())
但它无论如何都不起作用,卡在。reduce
:
请注意,如果我删除.reduce
步骤,它就会工作。在这种情况下,.window
提供的流量的处理在主流之后执行。我无法控制它,甚至无法得到最终结果。这没有任何意义。问题是因为我需要在进一步使用之前减少窗口
比如:
我是在我的映射器中的Mono中这样做的,但它阻止了那里的执行流,所以它不是一个正确的位置。它必须在窗口之后,在下次使用之前
正确的版本是:
Flux.range(0, 100)
.window(10)
.flatMap(window -> {
return window.reduce(new ArrayList<>(), (a, b) -> {
a.add(b);
return a;
});
})
.map((list) -> list.size())
.reduce(0, (a, b) -> a + b)
.doOnSuccess(System.out::println)
.subscribe();
通量范围(0,100)
.窗口(10)
.flatMap(窗口->{
返回窗口.reduce(新的ArrayList(),(a,b)->{
a、 添加(b);
返回a;
});
})
.map((列表)->list.size())
.减少(0,(a,b)->a+b)
.doOnSuccess(System.out::println)
.subscribe();
我正在将窗口转换为列表
,然后我可以在以下操作中使用此值。我最近一直在研究此问题。.window(3)
函数将其转换为通量。我认为,这可以通过嵌套订阅进行整洁的处理。当窗口为onComplete()
时,.buffer()
函数将通量转换为列表
这段代码是我的突破
Flux<Integer> flux = Flux.range(1, 10).log();
flux
.doOnNext(s -> logger.info("pre-window:{}", s))
.window(3)
.subscribe(s -> s.log().buffer().subscribe(t -> logger.info("post-window:{}", t)));
希望有帮助
Flux<Integer> flux = Flux.range(1, 10).log();
flux
.doOnNext(s -> logger.info("pre-window:{}", s))
.window(3)
.subscribe(s -> s.log().buffer().subscribe(t -> logger.info("post-window:{}", t)));
flux
.doOnNext(s -> logger.info("pre-buffer:{}", s))
.buffer(3)
.subscribe(t -> logger.info("post-buffer:{}", t));