【发布时间】:2020-02-11 15:11:03
【问题描述】:
我最近一直在学习使用 Java 中的反应器库和 Spring 框架的反应式编程,并且在大多数情况下我已经能够掌握它。但是,我发现自己有几次处于相同的情况,并且想就我哪里出错了一些建议。
我所苦苦挣扎的要点是,我经常想用单声道做一些事情,例如找到一些互补的数据,然后将其添加回原始单声道。 zip 函数在我看来是理想的候选者,但我最终订阅了原始单声道两次,这不是我的意图。
这是一个人为的示例,说明我一直在尝试解决的这种情况,因为我无法分享我的公司代码。它假设我们使用的是响应式数据库并设置了记录器,并且 Person 类是不可变的,但具有 with
public Mono<Person> getPersonWithFamilyMembers(Integer id){
log.info("Finding person with id {}", id);
personRepository.findById(id)
.switchIfEmpty(Mono.error(NotFoundException::new))
.doOnNext(person -> log.info("Found person: {}", person))
.as(this::fetchAndAddFamilyMembers)
.doOnSuccess(person -> log.info("Successfully found person with family members"));
}
private Mono<Person> fetchAndAddFamilyMembers(Mono<Person> personMono){
Mono<List<Person>> familyMembersMono = personMono
.map(Person::getFamilyId)
.flatMapMany(PersonRepository::findByFamilyId)
.collectList();
return personMono.zipWith(familyMembersMono, Person::withFamilyMembers);
}
运行这样的代码时我看到的输出是:
INFO | Finding person with id 1
INFO | Found person: Person(id=1, familyId=1, familyMembers=[])
INFO | Found person: Person(id=1, familyId=1, familyMembers=[])
INFO | Successfully found person with family members
这确实有意义,因为原始人 mono 已在两个地方订阅,我将其映射到 familyMembersMono 并且当我将它们压缩在一起时,但我不想对存储库进行不必要的调用,如果我可以避免它。
有没有人对处理这种行为的更好方法提出建议?
【问题讨论】:
标签: java project-reactor spring-reactive zipwith spring-reactor