反应性java mono.zip带有mono.empty()参数



使用spring with deactor项目将多个API调用作为汇总结果。可以使用mono.empty((参数返回null结果?

可以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

好吧,这当然不是一个优雅的解决方案,但是您可以选择在可选的内包装值:

Mono<Optional<Dog>> dogMono = Mono.just(Optional.empty());
if(condition1) {
    dogMono = dogApiClient.getDog().map(Optional::of);
}
Mono<Optional<Cat>> catMono = Mono.just(Optional.empty());
if(condition2) {
    catMono = catApiClient.getCat().map(Optional::of);
}
Mono<Optional<Horse>> horseMono = Mono.just(Optional.empty());
if(condition3) {
    horseMono = horseApiClient.getHorse().map(Optional::of);
}
Mono.zip(dogMono, catMono, horseMono)
    .map(this::mapToAnimals);
private Output mapToAnimals(Tuple3<Optional<Dog>, Optional<Cat>, Optional<Horse>> tuple3)
{
    Dog dog = tuple3.getT1().orElse(null);
    Cat cat = tuple3.getT2().orElse(null);
    Horse horse = tuple3.getT3().orElse(null);
    return new Output(dog, cat, horse);
}

在反应流中,禁止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;
}

如果您不能定义这些无空对象实例,则@yossarian的解决方案也可以工作。

请注意,API客户端调用仍然存在一个大问题,但是Mono.just(apiClient.blockingCall())模式。

在这里,您本质上是在内部的封锁呼叫

理想情况下,这些客户将返回Mono<Dog|Cat|Horse>以反映非阻滞性质。例如,使用适当的非阻滞API,可以像这样初始化dogMono

Mono<Dog> dogMono = (condition1) ? dogApiClient.getDogAsync() : Mono.just(NO_DOG);

最新更新