【问题标题】:Converting kotlin callbacks to Suspending: able to nest?将 kotlin 回调转换为暂停:能够嵌套?
【发布时间】:2020-02-12 18:30:19
【问题描述】:
我有一些棘手的 Android 回调(两个连续的可选身份验证步骤与用户交互),我正在尝试将它们转换为简单的挂起函数。
所以我从suspendCoroutine 开始,并且能够使第一个工作。耶!
但是第二个需要调用第一个。这似乎不是“正常”的做事方式,因为我不能从第二个调用第一个挂起函数。即使我将它包装在“启动”或“运行阻塞”中,它仍然会警告我做得不好。
“由于挂起函数的 CoroutineScope 接收器导致的歧义 coroutineContext”(可能是this?)
通常当 Kotlin 感到困惑时,这是因为我做出了错误的架构选择!如何制作嵌套的挂起函数(操作)?
双关语。
【问题讨论】:
标签:
kotlin
kotlin-coroutines
【解决方案1】:
您描述的这些挂起函数听起来像是在执行顺序操作。他们不需要启动新的协程。没有什么需要“嵌套”。它应该看起来像这样(两个返回字符串的不同回调的人为示例):
suspend fun SomeClass.doSomething(msg: String): String =
suspendCoroutine { cont ->
doSomething(msg, object: SomeCallback1 {
override fun onFinished(result: String) {
cont.resume(msg)
}
})
}
suspend fun SomeClass.doSomethingElse(msg: String): String =
suspendCoroutine { cont ->
doSomethingElse(msg, object: SomeCallback2 {
override fun onFinished(result: String) {
cont.resume(msg)
}
})
}
suspend fun SomeClass.doBothThingsInSuccession(msg: String): String {
val firstResult = doSomething(msg)
return doSomethingElse(firstResult)
}
如果您想隐藏详细信息,前两个挂起函数可以是私有的。或者您可以将所有内容组合成一个函数:
suspend fun SomeClass.doBothThingsInSuccession(msg: String): String {
val firstResult: String = suspendCoroutine { cont ->
doSomething(msg, object: SomeCallback1 {
override fun onFinished(result: String) {
cont.resume(result)
}
})
}
return suspendCoroutine { cont ->
doSomethingElse(firstResult, object: SomeCallback2 {
override fun onFinished(result: String) {
cont.resume(result)
}
})
}
}