java - 我的 Spring webflux flatMap、doOnNext、doFinally 没有被调用内部 Mono?
问题描述
我对反应堆完全陌生。我的 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 结束
解决方案
您的代码存在一些问题。
在 Reactor 中,在您订阅之前什么都不会发生。也就是说,仅仅创建一个 Mono 并没有做任何事情。在您传递给的函数中doOnNext
,您创建了一个从未订阅过的 Mono。因此,您传递给的函数flatMap
将永远不会被调用。尝试使用flatMap
而不是doOnNext
(您需要稍微摆弄一下类型才能使其正常工作)。
您测试它的方式的一个问题来自“组装时间”和“执行时间”之间的差异。在你所有的getMe*
方法中,你立即打印一些东西,然后返回一个 Mono。这实际上在调试时会产生误导,因为打印将在汇编期间发生,即使返回的 Mono 从未被执行。您可以在执行时执行副作用,而不是使用Mono.defer()
or Mono.fromSupplier()
。
使用数组来绕过 Java 对变量和 lambda 的限制的技术是不好的做法,虽然它在这种情况下可能有效,但您应该改掉这种习惯,因为它非常脆弱。要了解原因,请想象您的链中的某些 Mono 在另一个线程中执行昂贵的操作。这意味着您传递给的函数将在已经返回之后subscribe
被调用。 Final()
推荐阅读
- mysql - 同一聊天中两条消息的响应时间
- c# - 我需要在 Unity 中下载很多图像,但我的应用程序在生成 Sprite 时冻结
- c++ - 将任意 Eigen 对象写入行主要的普通存储
- android - Fragment onDetachFragment() 非法状态异常
- symfony - symfony 从虚拟主机获取参数
- corda - CordaApp 安装
- jenkins - Jenkins 查询 json api 以获取上次成功构建的详细信息
- java - 如何从字符串中提取浮点数并单独捕获到对象中?
- apache-spark-sql - cloudera 中的 Hbase-Spark 连接器问题:java.lang.AbstractMethodError
- c++ - VK_FILTER_NEAREST 在采样期间不工作