【问题标题】:Spring Webflux: efficiently using Flux and/or Mono stream multiple times (possible?)Spring Webflux:多次有效地使用 Flux 和/或 Mono 流(可能吗?)
【发布时间】:2021-03-10 21:12:56
【问题描述】:

我有下面的方法,我调用了几个 ReactiveMongoRepositories 来接收和处理某些文档。由于我是 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;
    }

【问题讨论】:

  • 我没有 IDE,所以无法编写示例,但您可以从获取指令开始。保留Mono&lt;Instruction&gt;,然后获取UserflatMap 用户并获取团队,然后flatMap 团队并构建一个由Mono&lt;Tuple&lt;User, Team&gt;&gt; 组成的Mono&lt;tuple&gt;。然后你拿你的 2 Monos 并使用 zipWithcombinator projectreactor.io/docs/core/release/api/reactor/core/publisher/… 并构建一个 Mono&lt;Tuple&lt;User, Team, Instruction&gt;&gt; ,你可以在上面进行平面映射。
  • 所以基本上取 2,然后取 1,然后组合成 3。您可以使用 Tuples.of(...) 函数创建元组
  • 基本上是要写给你@Toerktumlare 的建议。从他的描述中猜你应该可以做到。
  • @p.streef 如果您愿意,请继续写一个答案。我目前没有 IDE 来写东西。但是,如果您觉得自己想要,那没问题。
  • @Toerktumlare 非常感谢。这似乎在提高效率和可读性方面起到了作用。我正在采取的方法是朝着正确的方向,所以这也证实了这一点。非常感谢。我注意到的是,所有这些流都是用 MongoDB 开放的,与阻塞编程相比,MongoDB 需要大量连接到数据库。仍然需要对此进行调查,因为连接似乎堆积起来并且没有迅速关闭。

标签: spring spring-mvc spring-webflux project-reactor


【解决方案1】:

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

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

保留Mono&lt;Instruction&gt;,然后获取UserflatMapUser,并从数据库中获取Team。然后你flatMap 团队并建立一个由Mono&lt;Tuple&lt;User, Team&gt;&gt; 组成的Mono&lt;Tuple&gt;

之后,您使用您的 2 个 Monos 和 use zipWith with a Combinator function 并构建一个您可以平面映射的 Mono&lt;Tuple&lt;User, Team, Instruction&gt;&gt;

所以基本上获取 1 个项目,然后获取 2 个项目,然后将 Combinate 分成 3 个项目。您可以使用Tuples.of(...) 函数创建元组。

【讨论】:

    猜你喜欢
    • 2018-12-12
    • 2021-09-30
    • 2019-05-18
    • 2019-01-20
    • 2021-08-14
    • 2020-01-22
    • 2019-03-26
    • 2020-10-05
    • 2021-03-09
    相关资源
    最近更新 更多