Hec*_*tor 4 android kotlin arrow-kt
我正在研究我当前的 Android 应用程序中的 Kotlin 协程和通道。
我有以下代码来管理远程 Api 调用并控制 UI 副作用
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))
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码给了我想要的结果,但是我想将其重构为类似于函数式编程“铁路模式”的东西https://android.jlelse.eu/real-world-function-programming-with-kotlin-arrow- b5a98e72f5e3
我的流程在哪里
stepOne(Historical.completed)
.stepTwo(action.sideEffects)
.stepThree(getReaction())
.stepFour(reaction.sideEffects)
.finalStep(reaction)
Run Code Online (Sandbox Code Playgroud)
这将在任何步骤失败或历史“完成”时“短路”
Kotlin 中可以实现这种调用方式吗?和/或 Kotlin & Arrow.kt?
您可以使用 Arrow-kt 的Either。
您可以使用Either's mapLeft(),map(),flatMap()。
如果结果是Exception使用mapLeft(). 返回值将mapLeft()是新的Left结果Either,例如返回是String,结果将是Either<String, List<Any>>。如果结果是Right,即List<Any>,mapLeft()将被跳过,但结果类型无论如何都会改变,所以你将拥有类型Either<String, List<Any>>和 值Right<List<Any>>。如果您选择的话,您也可以返回相同的Exception内容mapLeft()
如果您不需要处理特定错误,您可以直接链接map()and flatMap()。map()基本上是mapRight(),flatMap()当你想要链接调用时很有用,即在链中的某个地方有一个接收器可能会失败,并且你想以相同的方式List<Any>处理该调用,你可以从返回新的ExceptionEitherEitherflatMap()
代码看起来像这样
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))
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1074 次 |
| 最近记录: |