android - Kotlin 流程,回调
问题描述
我创建了以下扩展功能:
fun <T> Flow<T>.handleErrors(showError: Boolean = false, retry: Boolean = false,
navigateBack: Boolean = true): Flow<T> =
catch { throwable ->
var message: String? = null
if (showError) {
when (throwable) {
is HttpException -> {
postEvent(EventType(retry))
}
}
}
然后扩展函数将 throwable 类型发布到 Base Activity,并根据发布的事件类型显示相关对话框。
如果事件是重试,我想重试失败的流程。
例如,如果 HTTP 异常是 400,我想在对话框中选择重试时重试失败的调用。
Kotlin
是否可以从不同的活动或片段向失败并可以调用的流添加回调?
解决方案
我认为您不想在单独的块中重试,您可以像这样组织代码
fun presentDialog(onClick: (Boolean) -> Unit) {
// some code to compile you dialog / install callbacks / show it
onClick(true) // user-click-retry
}
suspend fun main() {
val source = flow {
while (true) {
emit(
if (Math.random() > 0.5) Result.success(100) else Result.failure(IllegalArgumentException("woo"))
)
}
}
source.collect { result ->
suspendCancellableCoroutine<Unit> { cont ->
result.onSuccess {
println("we are done")
}.onFailure {
presentDialog { choice ->
if (choice) {
cont.resumeWith(Result.success(Unit))
} else {
println("we are done")
}
}
}
}
}
}
现在有一些解释
如你所知,flow 是冷的,如果你不收集它,它永远不会产生,因此,如果你的 collect 块没有返回,则flow
构建器中剩余的 thunkemit
将不会被执行,你暂停执行flow
通过调用块构建器suspendCoroutine
,collect
如果发生 HTTP 错误,您将显示您的对话框,并根据用户响应恢复执行,如果没有发生错误或用户只是不单击重试,则不要理会所有内容。上面的示例代码在某种程度上具有误导性,对于一般情况,当一切正常时,您不提供重试机制,因此while true
块可能会更改为
flow {
do {
val response = response()
emit(response)
} while(response.isFailure)
}.collect {
it.onSuccess { println("of-coz-we-are-done") }.onFailure {
// suspend execution and show dialog
// resume execution when user click retry
}
}
这可能会安慰你,流程有尽头,但实际上它基本上是一样的
推荐阅读
- graph-theory - 如何解决修正的旅行推销员问题?
- python - 我可以改变什么来让 k-means 以 Python 中预期的方式对我的数据进行聚类?
- android - 无法读取 packageName ':generateDebugBuildConfig'
- javascript - 如果在从数据库中获取数据后选中一个复选框,如何禁用其他复选框
- r - 如何为带有左对齐和右对齐文本的绘图添加标题
- c# - 对其中包含 Environment.Exit() 调用的方法进行单元测试
- swift - 我收到此错误“尝试将非属性列表对象设置为 NSUserDefaults”
- office365 - 客户端应用程序是否必须注册 Azure AD 才能访问 Microsoft Graph API?
- python - 如何使用python检查[dot]文件夹是否存在
- ios - 带有函数参数的 CoreData 谓词