2 回答
TA贡献1842条经验 获得超12个赞
好吧,这当然不是一个优雅的解决方案,但您可以选择将您的值包装在 Optional 中:
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);
}
TA贡献1846条经验 获得超7个赞
在 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);
添加回答
举报