使用fromCallable时onSubscribe来不及

时间:2018-08-27 11:54:16

标签: reactive-programming project-reactor

我经常要求在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()))中?

1 个答案:

答案 0 :(得分:0)

flatMapIterable尝试避免在检测到源为Iterable时执行完整的RS订阅和请求周期以获得Callable。而是直接调用call()方法。

这对于Flux.just(myList).flatMapIterable(list -> list)之类的情况很好。但是,我认为在Mono.fromCallable ...

上执行此操作可能会过于迫切

抑制此优化的Mono.fromCallable()的一种方法是在其后使用.hide()。对于.log(),这会将flatMapIterable可见的实例更改为非Callable的实例。