我正在使用Spring Reactor 3.1.0.M3,并且有一个用例,我需要合并来自多个源的Mono。我发现如果其中一个Mono是空Mono,zip会失败,并且没有错误。
示例:
Mono<String> m1 = Mono.just("A");
Mono<String> m2 = Mono.just("B");
Mono<String> m3 = Mono.empty();
Mono<String> combined = Mono.zip(strings -> {
StringBuffer sb = new StringBuffer();
for (Object string : strings) {
sb.append((String) string);
}
return sb.toString();
}, m1, m2, m3);
System.out.println("Combined " + combined.block());
当添加m3时,响应为空时,组合子被跳过。当删除m3时,它按预期工作并返回“AB”。有没有办法通过检测空的Mono来处理这个问题?还有,有没有办法让组合子方法知道对象的类型,而不必强制转换?
5条答案
按热度按时间68bkxrlz1#
zip运算符的行为不是这样的,它实际上是反直觉的:您的代码需要一个包含3个元素的元组,而您只得到了两个?!?
在这种情况下,您可以控制,只有您可以决定什么是一个好的默认值,如果没有提供(记住,
null
值是禁止的React流规范)。编辑
您似乎被
Publisher
类型的性质所迷惑,请参阅:如果其中一个Mono是空Mono,则压缩失败,没有错误
和
因此,如果我试图压缩Mono的,由于某种原因,其中一个是空的,压缩将失败,我似乎不能把任何代码来防止这种情况
空的
Mono
不是失败的情况:它只是没有发出任何值并且成功完成了。您可以通过更改代码示例来验证这一点:因此,根据您的要求,您可以:
Mono
示例上应用defaultIfEmpty
运算符Mono
上应用defaultIfEmpty
运算符,使用默认值,甚至将其转换为错误消息combined.switchIfEmpty(Mono.error(...))
q5iwbnjs2#
在
String
的情况下,为空的情况定义一个默认值是很容易的,这很好地解决了Brian的答案中所描述的问题。然而,对于其他自定义类型,由于这样或那样的原因,创建一个空对象可能很困难。这些情况下的一个替代方法是使用Optional
。尽管这个解决方案有一些沉重的样板。zaq34kh63#
单声道压缩
任何源的错误或空完成将导致其他源被取消,并且产生的Mono分别立即错误或完成。
当一个Mono源代码在没有值的情况下完成时,如果您仍然希望继续执行其他源代码,那么Mono.zipDelayError是您的最佳选择。
cdmah0mi4#
应为
Mono.zip
:同样,您可以传递
Mono.just(Optional.empty())
,而不是禁用null
或Mono.empty()
,传递zip()
。wsewodh25#
完全公开,我的例子基本上是Brian Clozel的,但对其他数据类型进行了小的编辑以突出显示。
例如,zip,将忽略空值的条目,例如Mono.empty。因此,要完成它,需要有一个非空值,在本例中是一个空字符串,但一个数据类型的新示例供您稍后在代码中检查也是不错的