我绝对不是反应堆新手。
我的flatMap,doOnNext,doFinally没有被内部Mono调用。
我添加了样本测试并描述了问题的输出。即使我将getMeIntegerMono2
与getMeStringMono
互换也不会被呼叫,
我在做错什么吗?
@Test
public void prodBug() {
System.out.println(Final());
}
String Final(){
final String[] val = new String[1];
System.out.println("1 - "+Thread.currentThread().getName());
Mono<Integer> intMono =
getMeIntegerMono("2")
.doOnNext(integer -> {
getMeIntegerMono2("21")
.flatMap(s -> getMeStringMono(String.valueOf(s)));
});
System.out.println("2 - "+Thread.currentThread().getName());
intMono.subscribe(integer -> {
val[0] =String.valueOf(integer);
});
System.out.println("3 - "+Thread.currentThread().getName());
return val[0];
}
Mono<String> getMeStringMono(String val){
System.out.println("String Mono - "+Thread.currentThread().getName());
return Mono.just(val);
}
Mono<Integer> getMeIntegerMono(String val){
System.out.println("Integer Mono - "+Thread.currentThread().getName());
return Mono.just(Integer.parseInt(val));
}
Mono<Integer> getMeIntegerMono2(String val){
System.out.println("Integer Mono2 - "+Thread.currentThread().getName());
return Mono.just(Integer.parseInt(val));
}
输出为
1 - main
Integer Mono - main
2 - main
Integer Mono2 - main
3 - main
2
以退出代码0结束的过程
答案 0 :(得分:1)
您的代码存在一些问题。
在Reactor中,nothing happens until you subscribe。也就是说,仅创建Mono并不会做任何事情。在传递给doOnNext
的函数中,创建一个从未订阅的Mono。因此,将永远不会调用传递给flatMap
的函数。尝试使用flatMap
而不是doOnNext
(您需要花一些时间弄些类型才能使其起作用)。
测试方法的一个问题来自“组装时间”和“执行时间”之间的difference。在所有getMe*
方法中,您都立即打印出一些内容,然后返回Mono。实际上,这在调试时会产生误导,因为即使在组装期间都不会执行返回的Mono,但打印仍会在组装期间进行。您可以在执行时执行副作用,而不要使用Mono.defer()
或Mono.fromSupplier()
。
使用数组来绕开Java对变量和lambda的限制的技术是一种不好的实践,尽管在这种情况下可能会起作用,但您应该摆脱这种习惯,因为它非常脆弱。要理解为什么,请想象您的链中的某些Mono在另一个线程中执行了昂贵的操作。这意味着您传递给subscribe
的函数将在 Final()
返回之后被调用。