【问题标题】:Zip Three Different Mono of Different Type拉链三个不同类型的不同单声道
【发布时间】:2020-02-15 02:49:54
【问题描述】:

我已经使用 Spring Webflux 开始了一个新项目,我对这种反应式编码范式相当陌生。对于像新手一样的提问,请提前道歉。

我的控制器方法将响应返回为Mono<ResponseEntity<String>>,我有三个不同的服务可以调用,我从中得到三个不同的Mono 对象,就像这样 -

Mono<CustomObject> customMono = serivce1.method();
Mono<Boolean> booleanMono = service2.method();
Mono<String> stringMono = service3.method();

所以为了准备响应(Mono&lt;ResponseEntity&lt;String&gt;&gt;),我需要做这样的事情 -

Mono.zip(customMono, booleanMono, stringMono, (customData, booleanData, stringData) -> {
------
return Mono.just(ResponseEntity.ok().body("-----"));
});

问题是,没有这样的zip 方法可以将3 个Mono 和一个函数作为参数。我已经找到了这个- https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#zip-reactor.core.publisher.Mono-reactor.core.publisher.Mono-java.util.function.BiFunction-

但它不符合我的要求。所以我面临的问题

  • 我不能使用 Mono.mergeWithMono.concaWith 方法,因为我的 Mono 对象属于不同类型。
  • 我可以对每个 Mono 进行平面映射/映射并创建一个链。但我希望 service2 在单独的线程中被并行调用,因为它不依赖于 service1 调用。但 service3 调用依赖于 service1 响应。

总结一下,我需要做的事情:

  • 首先调用 service1
  • 在不同的线程上分别调用 service2
  • 进行依赖于 service1 调用数据的 service3 调用
  • 使用来自所有服务调用的数据生成最终响应对象 (Mono&lt;ResponseEntity&lt;String&gt;&gt;)。

提前致谢。作为新手,欢迎提出任何建议。

【问题讨论】:

    标签: java spring-webflux reactor-netty


    【解决方案1】:

    当你压缩两个单声道时,第三个参数将是BiFunction,但对于三参数,它返回tupleflatmap,然后在元组中你将得到其他单声道的响应。 您需要通过以下方式修改您的代码。

    Mono.zip(customMono, booleanMono, stringMono).flatMap(data->{
     data.getT1();
     data.getT2();
     data.getT3();
     return <your_response_object>;
    });
    

    现在getT1()getT2()getT3() 的返回类型是什么?

    通常这将取决于您的 Zip Mono 返回什么。

    希望对你有所帮助。

    【讨论】:

    • 您能否建议一种方法如何使 service2 调用并行/异步?当我调用 Mono.zip 方法时,我希望 service2 响应可以立即使用。
    • 我认为下面的 Yash 答案有相同的解决方案。
    • 您能否解释一下为什么使用flatMap 而不是map 以及与简单地返回&lt;your_response_object&gt; 相比,Mono.just 最后做了什么?
    • 单声道超过8个怎么办? mono.zip 的最大值为 8
    • @GaudamThiyagarajan 然后你需要调用 data.getT8() 希望它会工作。压缩多达 8 个元素并请求高达 T8() 的数据。
    【解决方案2】:

    对于您的具体情况,您需要Mono.zipWhen(),这将确保您的第 3 次服务调用将具有来自服务调用 1 的响应所需的数据

    Mono.zip(monoResponse1,monoResponse2).zipWhen(data ->serviceCall3(data.getT1())).flatMap(response ->{
        response.getT1().getT1();//response from mono1
        response.getT1().getT2();//response from mono 2
        response.getT2();//response from mono 3
        return {create your mono response here};
    } );
    

    【讨论】:

    • 谢谢。您能否建议一种方法如何使 service2 调用并行/异步?当我调用 Mono.zip 方法时,我希望 service2 响应可以立即使用。
    • 您可以使用 data.getT2() 直接使用 service2 响应
    猜你喜欢
    • 2023-01-21
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    相关资源
    最近更新 更多