Kotlin Flow, Callback
Solution 1:
I don't think you want to retry in a separate block, you can organize your code like this
funpresentDialog(onClick: (Boolean) -> Unit) {
// some code to compile you dialog / install callbacks / show it
onClick(true) // user-click-retry
}
suspendfunmain() {
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")
}
}
}
}
}
}
now some explanations
as you already know, flow is cold,if you don't collect it, it will never produce, as a result, if your collect block does not return, the remaining thunk in flow
builder after emit
will not get executed,
you suspend the execution of flow
builder by calling suspendCoroutine
in collect
block, if an HTTP error occurs, you show your dialog, and resume the execution according to user response, if no error happens or users just don't click retry, leave everything alone. the sample code above is somehow misleading, for a general case, you don't supply a retry mechanism when everything goes fine, so the while true
block could change to
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
}
}
which may comfort you that the flow has an end, but actually it is basically the same
Post a Comment for "Kotlin Flow, Callback"