我经常要求在onSubscribe和onFinally执行一些逻辑,这可以很方便地通过
实现private <T> Mono<T> doAtStartAndEnd(Mono<T> source) {
return source.doOnSubscribe((s) -> {
System.out.println("ON SUBSCRIBE");
}).doFinally((f) -> {
System.out.println("ON FINALLY");
});
}
并通过以下链中的transform
使用它:
List<String> result = Mono.fromCallable(() -> getListOfStrings())
// .log()
.flatMapIterable(list -> list)
.map(String::toUpperCase)
.collectList()
.transform(this::doAtStartAndEnd)
.block();
当然,预期的行为是ON SUBSCRIBE
在调用可调用项(此处为getListOfStrings()
)之前出现在控制台中。但是MonoFlattenIterable
的订阅逻辑导致相反的行为。不仅flatMapIterable
就是这种情况,zip
之类的其他各种运算符也是如此。
如果我取消注释.log()
所在的行,则该链将按预期运行。
也许这与Reactive Gem #22中的完全相同,但是然后如何实现所需的行为,而无需再次包装Mono / Flux,例如在Mono.defer(() -> Mono.fromCallable(() -> getListOfStrings()))
中?
答案 0 :(得分:0)
flatMapIterable
尝试避免在检测到源为Iterable
时执行完整的RS订阅和请求周期以获得Callable
。而是直接调用call()
方法。
这对于Flux.just(myList).flatMapIterable(list -> list)
之类的情况很好。但是,我认为在Mono.fromCallable
...
抑制此优化的Mono.fromCallable()
的一种方法是在其后使用.hide()
。对于.log()
,这会将flatMapIterable
可见的实例更改为非Callable
的实例。