Android 如何实施";“铁路模式”;在Kotlin/Arrow.kt中,用于生产商频道
我正在调查我当前Android应用程序中的Kotlin协同程序和频道 我有以下代码来管理远程Api调用和控制UI副作用Android 如何实施";“铁路模式”;在Kotlin/Arrow.kt中,用于生产商频道,android,kotlin,arrow-kt,Android,Kotlin,Arrow Kt,我正在调查我当前Android应用程序中的Kotlin协同程序和频道 我有以下代码来管理远程Api调用和控制UI副作用 private val historical: CompletableDeferred<List<Any>> = CompletableDeferred() private val mutex = Mutex() @ExperimentalCoroutinesApi fun perform(action: Action):
private val historical: CompletableDeferred<List<Any>> = CompletableDeferred()
private val mutex = Mutex()
@ExperimentalCoroutinesApi
fun perform(action: Action): ReceiveChannel<List<Any>> =
produce {
mutex.withLock {
if (historical.isCompleted) {
send(historical.getCompleted())
return@produce
}
send(action.sideEffects)
val networkResponse = repository.perform(action)
send(networkResponse.sideEffects)
send(listOf(networkResponse)).also {
historical.complete(listOf(response))
}
}
}
在任何步骤出现故障或历史“完成”时,将“短路”
有可能在Kotlin实现这种通话风格吗?和/或Kotlin&Arrow.kt?您可以使用Arrow-kt
您可以使用的mapLeft()
,map()
,flatMap()
如果结果是异常
使用mapLeft()
。来自mapLeft()
的返回值将在结果other
中成为新的左
,例如返回值为String
,结果将为other
。如果结果是Right
,即List
,mapLeft()
将被跳过,但结果类型仍会更改,因此您将拥有类型或类型,值为Right
。如果选择,也可以从mapLeft()
返回相同的异常
如果您不需要处理特定的错误,您可以只链接map()
和flatMap()
map()
基本上是mapRight(),flatMap()
在您想要链接调用时非常有用,即在链的某个地方有一个List
的接收器,它可能会失败,并且您想要以与Orther
相同的方式处理异常
对于该调用,您可以从flatMap()返回新的Orther
代码看起来像这样
fun perform(action: Either<Exception, Action>): ReceiveChannel<List<Any>> =
produce {
// if action is always right, you can start it as Right(action) but then first mapLeft does not make any sense
if (historical.completed) action
.mapLeft {
// handle actions exception here
// transform it to something else or just return it
send(action.sideEffects)
it
}.flatMap {
// handle right side of action either
// assume here that repository may fail and returns Either<Exception, NetworkResponse>
repository.perform(it)
}.mapLeft {
// handle repositorys exception here
// transform it to something else or just return it
send(it)
it
}.map {
// handle network response
send(listOf(networkResponse))
historical.complete(listOf(networkResponse))
}
}
fun perform(动作:任选一个):ReceiveChannel=
产生{
//如果行动总是正确的,你可以从正确的(行动)开始,但第一步是没有任何意义的
如果(历史。已完成)操作
mapLeft先生{
//在此处理操作异常
//将其转换为其他内容或只是将其返回
发送(操作。副作用)
信息技术
}.平面图{
//处理行动的右侧
//这里假设存储库可能失败并返回
存储库。执行(it)
}mapLeft先生{
//在此处处理Repository异常
//将其转换为其他内容或只是将其返回
发送(it)
信息技术
}.地图{
//处理网络响应
发送(网络响应列表))
历史。完成(列表(网络响应))
}
}
不确定您的代码的作用。。。。但是,使用Kotlin和Arrow可以实现面向铁路的编程。检查一下:如果每一个都返回一个可观察到的,你也许可以这样做。请参阅RxJava和RxKotlinRailway面向铁路的编程概念在Kotlin中通过中缀函数工作,用于相同类型的输入和输出,结果不同。你能提供一些关于你的代码的更多信息(什么是函数和I/O)以便我能更好地帮助你实现你的方法吗?你可以实现ROP而不用Arrow-。即使使用箭头“或”,代码的可读性也会稍差一些(平面图可能会妨碍步骤的阅读,就像您在问题中编写的那样)。您可能需要在上面添加一个中缀,我想知道为什么在这两种类型上都没有.onLeft{…}方法。当然,做一个mapLeft是可行的,但是必须始终返回“它”是很尴尬的。我现在更喜欢.if(it.isLeft())…}。或者,应用{if(isLeft())…}@Zordid,我想这样你就可以一个接一个地链接调用,并在一个地方处理所有调用的错误。否则,您将无法返回任何内容。自定义扩展功能。我想onLeft可以完成这项工作。真实产品中的iirc。mapLeftReturn扩展函数
fun perform(action: Either<Exception, Action>): ReceiveChannel<List<Any>> =
produce {
// if action is always right, you can start it as Right(action) but then first mapLeft does not make any sense
if (historical.completed) action
.mapLeft {
// handle actions exception here
// transform it to something else or just return it
send(action.sideEffects)
it
}.flatMap {
// handle right side of action either
// assume here that repository may fail and returns Either<Exception, NetworkResponse>
repository.perform(it)
}.mapLeft {
// handle repositorys exception here
// transform it to something else or just return it
send(it)
it
}.map {
// handle network response
send(listOf(networkResponse))
historical.complete(listOf(networkResponse))
}
}