Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.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
Android 如何实施";“铁路模式”;在Kotlin/Arrow.kt中,用于生产商频道_Android_Kotlin_Arrow Kt - Fatal编程技术网

Android 如何实施";“铁路模式”;在Kotlin/Arrow.kt中,用于生产商频道

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):

我正在调查我当前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))
                }
            }
        }
在任何步骤出现故障或历史“完成”时,将“短路”

有可能在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))
            }
    }