gpt4 book ai didi

java - 将两个 Mono 组合在一起,其中第二个 Mono 订阅第一个 Mono

转载 作者:行者123 更新时间:2023-12-02 09:00:51 27 4
gpt4 key购买 nike

我最近一直在使用 Java 中的 react 器库和 Spring 框架学习响应式(Reactive)编程,并且在很大程度上我已经能够掌握它。然而,我发现自己多次遇到同样的情况,并希望得到一些关于我哪里出错的建议。

我正在努力解决的要点是我经常想用单声道做一些事情,例如找到一些免费数据,然后将其添加回原始单声道。 zip 函数在我看来是理想的候选者,但最终我订阅了原始的 mono 两次,这不是我的意图。

这是一个人为的示例,说明了我一直在尝试解决的情况类型,因为我无法共享我的公司代码。它假设我们使用响应式(Reactive)数据库并设置了记录器,并且 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

这确实有意义,因为原始的 person mono 已在两个地方订阅,我将其映射到 familyMembersMono 以及当我将它们压缩在一起时,但我不想做不必要的事情如果我可以避免调用存储库。

有人对处理此类行为有更好的建议吗?

最佳答案

一般来说,您不会将数据“添加”到 Mono,而是添加其中的数据。考虑到这一点,请使用 flatMap 而不是 as:

public Mono<Person> getPersonWithFamilyMembers(Integer id){
log.info("Finding person with id {}", id);

return personRepository.findById(id)
.switchIfEmpty(Mono.error(NotFoundException::new))
.doOnNext(person -> log.info("Found person: {}", person))
.flatMap(this::fetchAndAddFamilyMembers)
.doOnSuccess(person -> log.info("Successfully found person with family members"));
}

private Mono<Person> fetchAndAddFamilyMembers(Person person){ // this accepts Person, not Mono<Person>
return personRepository.findByFamilyId(person.getFamilyId())
.collectList()
.map(person::withFamilyMembers);
}

关于java - 将两个 Mono 组合在一起,其中第二个 Mono 订阅第一个 Mono,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60171972/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com