猿问

带有 Mono.empty() 参数的 Reactive Java Mono.zip

使用 Spring 和 Reactor Project 将多个 api 调用压缩为聚合结果。带有 Mono.empty() 参数的 Mono.zip() 可以返回空结果吗?


Mono<Dog> dogMono = dogApiClient.getDog(); // can return Mono.empty()

Mono<Cat> catMono = catMono = catApiClient.getCat(); // can returnMono.empty()

Mono<Horse> horseMono = horseApiClient.getHorse(); // can return Mono.empty()


Mono.zip(dogMono, dogMobo, horseMono)

  .map(this::mapToAnimals);

预期结果:


{

  dog: null, // if dog is null

  cat: null, // if cat is null

  horse: null, // if horse is null

}

实际结果:


{

  dog: {

    name: null,

    surname: null

  }, 

  cat: {

    name: null,

    surname: null

  }, 

  horse: {

    name: null,

    surname: null

  }

}

或者


"" // empty


慕尼黑8549860
浏览 183回答 2
2回答

红颜莎娜

好吧,这当然不是一个优雅的解决方案,但您可以选择将您的值包装在 Optional 中:Mono<Optional<Dog>> dogMono = Mono.just(Optional.empty());if(condition1) {&nbsp; &nbsp; dogMono = dogApiClient.getDog().map(Optional::of);}Mono<Optional<Cat>> catMono = Mono.just(Optional.empty());if(condition2) {&nbsp; &nbsp; catMono = catApiClient.getCat().map(Optional::of);}Mono<Optional<Horse>> horseMono = Mono.just(Optional.empty());if(condition3) {&nbsp; &nbsp; horseMono = horseApiClient.getHorse().map(Optional::of);}Mono.zip(dogMono, catMono, horseMono)&nbsp; &nbsp; .map(this::mapToAnimals);private Output mapToAnimals(Tuple3<Optional<Dog>, Optional<Cat>, Optional<Horse>> tuple3){&nbsp; &nbsp; Dog dog = tuple3.getT1().orElse(null);&nbsp; &nbsp; Cat cat = tuple3.getT2().orElse(null);&nbsp; &nbsp; Horse horse = tuple3.getT3().orElse(null);&nbsp; &nbsp; return new Output(dog, cat, horse);}

喵喵时光机

在 Reactive Streams 中,该null值是禁止的。此外,zip期望所有组合的发布者具有相同数量的元素。或者换句话说:一旦其中一个发布者完成,它就会短路。因此,如果您使用Mono.empty(),它会Mono立即完成并触发 也zip完成为空。一种可能的解决方案是为每只动物创建一个“空对象”实例,如下所示:public static final Dog NO_DOG = new Dog(...);public static final Cat NO_CAT = new Cat(...);public static final Horse NO_HORSE = new Horse(...);Mono<Dog> dogMono = (condition1) ? Mono.just(dogApliClient.getDog()) : Mono.just(NO_DOG);Mono<Cat> catMono = (condition2) ? Mono.just(catApliClient.getCat()) : Mono.just(NO_CAT);Mono<Horse> horseMono = (condition3) ? Mono.just(horseApliClient.getHorse()) : Mono.just(NO_HORSE);Mono.zip(dogMono, catMono, horseMono)    .map(Animals::fromDogCatAndHorse);Map<String, Object> fromDogCatAndHorse(Tuple3<Dog, Cat, Horse> tuple) {    Map<String, Object> forJson = new HashMap<>(3);    Dog dog = tuple.getT1();    if (dog = NO_DOG) json.put("dog", null); else json.put("dog", dog);    Cat cat = tuple.getT2();    if (cat = NO_CAT) json.put("cat", null); else json.put("cat", cat);    Horse horse = tuple.getT3();    if (horse = NO_HORSE) json.put("horse", null); else json.put("horse", horse);    return forJson;}请注意,api 客户端调用仍然存在一个大问题:Mono.just(apiClient.blockingCall())模式。在这里,您实际上是在本应是非阻塞控制器的内部硬塞一个阻塞调用...理想情况下,这些客户端将返回 aMono<Dog|Cat|Horse>以反映非阻塞性质。例如,使用适当的非阻塞 API,dogMono可以像这样初始化:Mono<Dog> dogMono = (condition1) ? dogApiClient.getDogAsync() : Mono.just(NO_DOG);
随时随地看视频慕课网APP

相关分类

Java
我要回答