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()
}