Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 项目反应器-如何按窗口处理结果_Java_Spring_Reactive Programming_Project Reactor - Fatal编程技术网

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));