首页 > 解决方案 > 执行多个反应操作的正确方法

问题描述

我从反应式存储库中获取Mono<FooBar>基于它的值我必须创建另外两个对象使用反应式存储库保存它们,修改FooBar对象并保存它。

由于我是响应式编程的新手,因此我使用了以下解决方案,该解决方案正在运行,但我不确定我是否正确使用了响应式 API:

@Test
void createAndSave() {
    Mono<FooBar> fooBarMono = findFooBar()  // returns Mono<FooBar>
            .map(fooBar -> {
        createAndSaveLoremBar(fooBar).subscribe();   // returns Mono<LoremBar>
        createAndSaveDoloremBar(fooBar).subscribe(); // returns Mono<DoloremBar>

        fooBar.setActive(true);

        return saveFooBar(fooBar);          // returns Mono<FooBar>
    }).flatMap(Function.identity());

    StepVerifier.create(fooBarMono)
            .expectNextMatches(Objects::nonNull)
            .expectComplete()
            .verify();

}

从控制台日志:

   saved lorem bar
   saved dolorem bar
   saved foo bar

标签: spring-data-mongodbspring-webflowproject-reactor

解决方案


我认为下面的解决方案更具可读性。无论如何,亚历山大是正确的,你永远不应该修改输入。你看我们从函数式编程中借用了很多概念。比如你叫Function.identity()这个叫 identity functorFlux和都是Mono单子。还有一个对这些人来说是秘密的概念,叫做Referential transparency命令式更新中断。

    final Mono<FooBar> fooBarMono1 = findFooBar()
            .zipWhen((fooBar) -> createAndSaveLoremBar(fooBar))
            .map(tuple -> tuple.getT1())
            .zipWhen((fooBar) -> createAndSaveDoloremBar(fooBar))
            .map(tuple -> tuple.getT1())
            .map(fooBar -> new FooBar(true))
            .flatMap(fooBar -> saveFooBar(fooBar));

或者更简洁:

    final Mono<FooBar> fooBarMono1 = findFooBar()
            .zipWhen((fooBar) -> createAndSaveLoremBar(fooBar)
                                    .then(createAndSaveDoloremBar(fooBar)))
            .map(tuple -> tuple.getT1())
            .map(fooBar -> new FooBar(true))
            .flatMap(fooBar -> saveFooBar(fooBar));

推荐阅读