首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用组合器函数压缩8个以上的mono

如何使用组合器函数压缩8个以上的mono
EN

Stack Overflow用户
提问于 2019-09-04 13:37:26
回答 4查看 5.5K关注 0票数 4

我通过调用每个项目的多个web服务来丰富数据,这些服务是以前的webservice调用(即扇出)的结果。

我正在使用Kotlin,Spring 2和新的反应性WebClient。

在这段代码片段中,我只展示了向end服务扩展的代码,但实际上,这是在一个更大的管道的末尾。

以前我一直使用Mono.zip(t1、t2、t3)接口,它支持传递最多8个值,并返回一个具有正确类型的元组。

定义:

代码语言:javascript
复制
    public static <T1, T2, T3, T4, T5, T6, T7, T8> Mono<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>> zip(Mono<? extends T1> p1,
            Mono<? extends T2> p2,
            Mono<? extends T3> p3,
            Mono<? extends T4> p4,
            Mono<? extends T5> p5,
            Mono<? extends T6> p6,
            Mono<? extends T7> p7,
            Mono<? extends T8> p8) {
        return onAssembly(new MonoZip(false, a -> Tuples.fromArray((Object[])a), p1, p2, p3, p4, p5, p6, p7, p8));
    }

我现在有超过8个服务要调用,所以我正在查看Mono.zip(combinatorFn,.组合调用结果的方法。

定义:

代码语言:javascript
复制
    public static <R> Mono<R> zip(Function<? super Object[], ? extends R> combinator, Mono<?>... monos) {
        if (monos.length == 0) {
            return empty();
        }
        if (monos.length == 1) {
            return monos[0].map(d -> combinator.apply(new Object[]{d}));
        }
        return onAssembly(new MonoZip<>(false, combinator, monos));
    }

我在使用KOTLIN时遇到了问题,在调用站点上定义combinator函数有困难。以下是我到目前为止所拥有的:

代码语言:javascript
复制
val tst: (Array<Any>) -> Mono<AggregateReport> = { it -> Mono.just(AggregateReport("Test")) }


val res = Mono.zip(
        tst,
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono()
)

显然,我需要增强combinator来实际处理输入数组并生成聚合。但是,该代码目前没有编译。

编译错误:

代码语言:javascript
复制
Error:(339, 41) Kotlin: Type mismatch: inferred type is (Array<Any>) -> Mono<ConsoleApplication.AggregateReport> but Function<in Array<(out) Any!>!, out (???..???)> was expected

有什么建议吗?

谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-09-06 14:45:11

经过一些额外的研究,我发现反应堆有Kotlin扩展,它为组合N个monos提供了一个具有更好方法签名的zip函数。

IE - fun <R> zip(vararg monos: Mono<*>, combinator: (Array<*>) -> R): Mono<R>

通过这种方式,我能够提供一个组合器,该组合器需要一个Array,并返回一个Mono。我实现了一个通用组合器,它可以检查传入响应的类型,并对聚合的各种属性的正确子类进行断言。

https://github.com/reactor/reactor-kotlin-extensions

票数 2
EN

Stack Overflow用户

发布于 2019-09-04 17:47:55

在纯kotlin里你不能这么做。

您在问题描述中显示的方法zip的签名要求Function类型,即java类型。

这个(kotlin one):

代码语言:javascript
复制
    val kotlin: (List<String>) -> String = { array: List<String> -> "kotlin" }

不等同于(java):

代码语言:javascript
复制
    Function<List<String>, String> java = array -> "java"
票数 0
EN

Stack Overflow用户

发布于 2019-09-04 20:52:05

你能做的是:

代码语言:javascript
复制
import reactor.core.publisher.Mono
import java.util.function.Function

...

fun main() {
    val tst = Function<Array<Any>, Mono<AggregateReport>> { Mono.just(AggregateReport("Test")) }

    Mono.zip(
        tst,
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono(),
        Client.callThatReturnsAMono()
    )
}

实际上,您必须使用java.util.function.Function类型,但是Kotlin正在帮助使它看起来更好看一些。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57789649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档