Spring Webflux:多次高效地使用Flux和/或单流(可能吗?)

Spring Webflux:多次高效地使用Flux和/或单流(可能吗?),spring,spring-mvc,spring-webflux,project-reactor,Spring,Spring Mvc,Spring Webflux,Project Reactor,我有下面的方法,在这里我调用几个ReactiveMongorPositories来接收和处理某些文档。因为我是Webflux的新手,所以我边走边学习 我觉得下面的代码不是很有效,因为我同时打开了多个流。这种非阻塞的代码编写方式使得从流中获取一个值并在后续级联平面图中重用该值变得复杂 在下面的示例中,我必须调用userRepository两次,因为我希望在开始时调用用户,然后再调用。有没有可能通过Webflux更有效地实现这一点 public Mono<Guideline> a

我有下面的方法,在这里我调用几个ReactiveMongorPositories来接收和处理某些文档。因为我是Webflux的新手,所以我边走边学习

我觉得下面的代码不是很有效,因为我同时打开了多个流。这种非阻塞的代码编写方式使得从流中获取一个值并在后续级联平面图中重用该值变得复杂

在下面的示例中,我必须调用userRepository两次,因为我希望在开始时调用用户,然后再调用。有没有可能通过Webflux更有效地实现这一点

    public Mono<Guideline> addGuideline(Guideline guideline, String keycloakUserId) {
        Mono<Guideline> guidelineMono = userRepository.findByKeycloakUserId(keycloakUserId)
                .flatMap(user -> {
                    return teamRepository.findUserInTeams(user.get_id());
                }).zipWith(instructionRepository.findById(guideline.getInstructionId()))
                .zipWith(userRepository.findByKeycloakUserId(keycloakUserId))
                .flatMap(objects -> {
                    User user = objects.getT2();
                    Instruction instruction = objects.getT1().getT2();
                    Team team = objects.getT1().getT1();
                    if (instruction.getTeamId().equals(team.get_id())) {
                        guideline.setAddedByUser(user.get_id());
                        guideline.setTeamId(team.get_id());
                        guideline.setDateAdded(new Date());
                        guideline.setGuidelineStatus(GuidelineStatus.ACTIVE);
                        guideline.setGuidelineSteps(Arrays.asList());
                        return guidelineRepository.save(guideline);
                    } else {
                        return Mono.error(new InstructionDoesntBelongOrExistException("Unable to add, since this Instruction does not belong to you or doesn't exist anymore!"));
                    }
                });
        return guidelineMono;
    }
public Mono-addGuideline(Guideline-Guideline,字符串keydovepuserid){
Mono-guidelineMono=userRepository.findbykeyDoppeUserId(keyDoppeUserId)
.flatMap(用户->{
return teamRepository.findUserInTeams(user.get_id());
}).zipWith(instructionRepository.findById(guideline.getInstructionId()))
.zipWith(userRepository.findbykeydeposteuserid(keydeposteuserid))
.flatMap(对象->{
User=objects.getT2();
指令=objects.getT1().getT2();
团队=objects.getT1().getT1();
if(instruction.getTeamId().equals(team.get_id())){
setAddedByUser(user.get_id());
guideline.setTeamId(team.get_id());
指南.setDateAdded(新日期());
guideline.setGuidelineStatus(GuidelineStatus.ACTIVE);
guideline.setGuidelineSteps(Arrays.asList());
返回指南repository.save(指南);
}否则{
返回Mono.error(新指令DOESNTBELONGOREXISTEPTION(“无法添加,因为此指令不属于您或不再存在!”);
}
});
返回指南Mono;
}

我将发布我之前的评论作为答案。如果有人想为它编写正确的代码,那就继续吧

我没有访问当前IDE的权限,因此无法编写示例,但您可以从数据库获取指令开始

保留该
Mono
,然后从数据库中获取
用户
flatMap
用户,并获取
团队
。然后您将
flatMap
团队,并构建一个由
Mono
组成的
Mono

在那之后,你用你的2个
Mono
s构建一个
Mono
,你可以在上面进行平面映射


所以基本上取1个项目,然后取2个项目,然后将组合成3个项目。您可以使用(…)的Tuples.of创建元组。

我没有IDE,因此无法编写示例,但您可以从获取指令开始。保留该
Mono
然后获取
User
flatMap
用户并获取团队,然后
flatMap
团队并构建一个由
Mono
组成的
Mono
。然后你把你的2个
Monos
和一个
combinator
一起使用
zipWith
,构建一个
Mono
,你可以平面映射。所以基本上取2,然后取1,然后组合成3。您可以使用
Tuples.of(…)
函数创建元组,该函数将基本上按照@Toerktumlare的建议编写。我猜你应该可以从他的描述中找到答案。@p.streef如果你愿意,就写一个答案吧。我目前没有IDE来写东西。“但如果你想要,那就没问题了。”托尔库姆拉尔非常感谢你。这似乎成功地提高了它的效率和可读性。我所采取的方法是正确的,因此这也证实了这一点。谢谢。我注意到的是,所有这些流都是使用MongoDB打开的,与阻塞编程相比,MongoDB需要大量连接到DB。仍然需要对此进行调查,因为连接似乎正在堆积,并且没有很快关闭。