我有需要与两个反应性依赖项交互的代码-保存到数据库并发布到流,每个都返回Mono
实例。之后,我需要做更多的处理-全部使用开始的原始对象,如下所示:
val myObject = Mono.just(“thing”);
myObject.flatMap(repository::save)
.flatMap(stream::publish)
.map(obj -> moreProcessing(obj));
但是问题是,repository.save
不会返回我感兴趣的对象的Mono
,stream.publish
也不会返回。
我可以通过以下方式实现我想要的东西:
myObject.flatMap(obj -> repository.save(obj).then(Mono.just(obj))
.flatMap(obj -> stream.publish(obj).then(Mono.just(obj))
.map(obj -> moreProcessing(obj));
即映射到依赖函数只是为了获得其行为,然后再次直接映射,但这似乎很奇怪-就像我可能会缺少一些更好的使用API的方法,这种方法并没有提示我在类型之间进行映射,因为实际上,这不是我使用的flatMap
。
我还可以使用类似的东西:
myObject.flatMap(obj ->
repository.save(obj)
.flatMap(x -> publisher.stream(obj))
.map(x -> moreProcessing(obj)));
但这也不是一个好方法,因为即使在相对简单的情况下,它也会导致难以维护的代码。
有想法吗?
答案 0 :(得分:0)
我有一个类似的问题,我使用下面的代码解决了。我认为重要的是不要不惜一切代价迷失方法链。过度挑战很容易创建难以阅读的结构。
@Test
public void mergeMonos(){
Mono<String> myObject = Mono.just("my object");
Mono<String> savedToDB = saveToDb(myObject);
Mono<String> savedToStream = saveToStream(myObject);
//if you need to wait for the first two to complete
Flux.concat(savedToDB, savedToStream, myObject)
.last()
.subscribe(System.out::println);
//if you don't need to wait for the db and stream
Flux.merge(savedToDB, savedToStream, myObject)
.last()
.subscribe(System.out::println);
}
private Mono<String> saveToStream(Mono<String> myObject) {
return myObject.map(t-> "saved to stream");
}
private Mono<String> saveToDb(Mono<String> myObject) {
return myObject.map(t-> "saved to db");
}
答案 1 :(得分:0)
您尝试过thipWhen
吗?如果rightGenerator
的结果为空(没有下一个信号),它的行为就像您希望的那样,有唯一的限制,它立即完成。因此,您需要返回Optional
或使用thenReturn
或switchIfEmpty
。
答案 2 :(得分:0)
避免丢失任何参考文献的一种方法可能是:
Mono<User> monoUser = userRepository.findByUsername(username)
.filter(u -> validatePassword(pass, u.getPassword()));
Mono<Clinic> monoClinic = monoUser.flatMap(u -> clinicRepository.findByUserId(u.getId()));
return Mono.zip(monoUser, monoClinic, (u,c) -> proccess(u, c));
第一个 Mono 返回一个用户,第二个 Mono 使用第一个 Mono 返回的用户并返回一个诊所,返回的 Mono(第三个 Mono)使用第一个 Mono 的输出和第二个 Mono 的输出创建一个不同的对象(由使用用户和诊所的过程方法返回)