Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 如何在Arrow+;反应器单子理解_Kotlin_Project Reactor_Arrow Kt - Fatal编程技术网

Kotlin 如何在Arrow+;反应器单子理解

Kotlin 如何在Arrow+;反应器单子理解,kotlin,project-reactor,arrow-kt,Kotlin,Project Reactor,Arrow Kt,在下面的代码段中,每个helloX()方法都是异步运行的(它是一个在单独线程中运行的延迟Mono),请参见下面的完整代码): 我怎样才能使它们并行执行,并在所有结果都完成后,在单子理解中聚合所有结果 包含main方法()的完整代码: 类HelloServiceImpl:HelloService{ private val logger=LoggerFactory.getLogger(javaClass) 重写fun helloEverybody():种类{ 返回MonoK.monad().fx.m

在下面的代码段中,每个
helloX()
方法都是异步运行的(它是一个在单独线程中运行的延迟Mono),请参见下面的完整代码):

我怎样才能使它们并行执行,并在所有结果都完成后,在单子理解中聚合所有结果

包含main方法()的完整代码:

类HelloServiceImpl:HelloService{
private val logger=LoggerFactory.getLogger(javaClass)
重写fun helloEverybody():种类{
返回MonoK.monad().fx.monad{
val j=!helloJoey()
val j2=!helloJohn()
val j3=!helloMary()
“$j和$j2和$j3”
}.fix()
}
重写fun helloJoey():种类{
返回Mono.defer{
logger.info(“helloJoey()”)
睡眠(2000年)
logger.info(“helloJoey()-ready”)
Mono.just(“你好,乔伊”)
}.subscribeOn(Schedulers.elastic()).k()
}
重写fun helloJohn():种类{
返回Mono.defer{
logger.info(“helloJohn()”)
睡眠(5000)
logger.info(“helloJohn()-ready”)
Mono.just(“你好,约翰”)
}.subscribeOn(Schedulers.elastic()).k()
}
覆盖有趣的helloMary():种类{
返回Mono.defer{
logger.info(“helloMary()”)
睡眠(5000)
logger.info(“helloMary()-ready”)
Mono.just(“你好,玛丽”)
}.subscribeOn(Schedulers.elastic()).k()
}
}
主要内容(){
val countDownLatch=countDownLatch(1)
HelloServiceImpl().helloEverybody().fix().mono.subscribe{
println(it)
倒计时闩锁
}
倒计时闩锁。等待()
}
更新

我采用了将顺序操作与并行操作相结合的方法:

    override fun helloEverybody(): Kind<ForMonoK, String> {
        return MonoK.async().fx.async {
            val j = helloJoey().bind()
            val j2= Dispatchers.IO
                    .parMapN(helloJohn(), helloMary()){ it1, it2 -> "$it1 and $it2" }
            "$j and $j2"
        }
    }
override fun helloEverybody():种类{
返回MonoK.async().fx.async{
val j=helloJoey().bind()
val j2=Dispatchers.IO
.parMapN(helloJohn(),helloMary()){it1,it2->“$it1和$it2”}
“$j和$j2”
}
}
不幸的是,parMapN不能与ForMonoK一起使用:

Type inference failed: fun <A, B, C, D> CoroutineContext.parMapN(fa: Kind<ForIO, A>, fb: Kind<ForIO, B>, fc: Kind<ForIO, C>, f: (A, B, C) -> D): IO<D>
cannot be applied to
receiver: CoroutineDispatcher  arguments: (Kind<ForMonoK, String>,Kind<ForMonoK, String>,Kind<ForMonoK, String>,(String, String, String) -> String)
类型推断失败:fun CoroutineContext.parMapN(fa:Kind,fb:Kind,fc:Kind,f:(A,B,C)->D):IO
不能应用于
接收方:CoroutineDispatcher参数:(种类,种类,种类,(字符串,字符串,字符串)->String)

思想?

flatMap
,与
map
一样,没有线程语义或并行性。您所追求的是
parMap
parTraverse
,它并行运行多个
MonoK

此时,
fx
块就变得不必要了,因为它是为顺序操作而设计的。你可以两者混合搭配

MonoK.async().fx.async {

  val result = 
    Dispatchers.IO
     .parMap(helloJoey(), helloMary()) { joe, mary -> ... }
     .bind()

  otherThing(result).bind()

}

我尝试过混合顺序和并行操作。然而,parMapN期望的是ForIO而不是ForMonoK???请参阅更新的问题extfun可能仅为IO定义,您是对的。这就是您想要的:我相信我们没有Reactor的并发实例,所以您可能需要使用Reactor的操作符来实现并行。
    override fun helloEverybody(): Kind<ForMonoK, String> {
        return MonoK.async().fx.async {
            val j = helloJoey().bind()
            val j2= Dispatchers.IO
                    .parMapN(helloJohn(), helloMary()){ it1, it2 -> "$it1 and $it2" }
            "$j and $j2"
        }
    }
Type inference failed: fun <A, B, C, D> CoroutineContext.parMapN(fa: Kind<ForIO, A>, fb: Kind<ForIO, B>, fc: Kind<ForIO, C>, f: (A, B, C) -> D): IO<D>
cannot be applied to
receiver: CoroutineDispatcher  arguments: (Kind<ForMonoK, String>,Kind<ForMonoK, String>,Kind<ForMonoK, String>,(String, String, String) -> String)
MonoK.async().fx.async {

  val result = 
    Dispatchers.IO
     .parMap(helloJoey(), helloMary()) { joe, mary -> ... }
     .bind()

  otherThing(result).bind()

}