-
Notifications
You must be signed in to change notification settings - Fork 1.9k
How to use Flows in an imperative mode? #4113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
A flow is "cold", so on its own it can't be used in the way you describe. It's only active when the consumer is collecting it, and all of its state lives inside the To turn it into a stateful "hot" stream of values, we can add an additional producer coroutine using With myCoroutineScope.launch {
val flow = myComponent.getSomeThings()
val channel = flow.produceIn(this)
for (item in channel) {
…
}
} Since the producer coroutine is now responsible for the lifecycle of the flow, including any resources it might hold, it's important to use correct structured concurrency to ensure everything's cleaned up afterwards. |
Every flow operator is open-source and fairly short. You can replace it with its implementation by getting rid of a few optimizations. originalFlow
.onStart { /* START */ } becomes
originalFlow
.onStart { /* START */ }
.onEmpty { /* EMPTY */ } becomes flow {
var isEmpty = true
flow {
/* START */
emitAll(originalFlow)
}.collect {
isEmpty = false
emit(it)
}
if (isEmpty) {
/* EMPTY */
}
} With flow {
flow {
var isEmpty = true
flow {
/* START */
emitAll(originalFlow)
}.collect {
isEmpty = false
emit(it)
}
if (isEmpty) {
/* EMPTY */
}
}.collect {
/* EACH */
emit(it)
}
} and so on. |
https://youtrack.jetbrains.com/issue/KT-33851/iterator-less-for-statement-operator-convention in the future also might help w.r.t. more imperative usages Another option is to transform flow into the channel via But in general, our consensus is that we do intend to provide one more way to consume the flow which is drastically different (semantics-wise and performance-wise) than the regular pull model. |
Use case
Suspending functions and the code in a coroutine can be used like normal imperative code.
But Flows can be used only in a reactive way (on X do Y).
I'm just curious, is there any way to use Flows like "regular" code?
Example of current declarative way:
to be written like this:
The Shape of the API
Something like the above example. I'm not sure if all the functionalities of various Flow operators can be achieved in imperative code.
The text was updated successfully, but these errors were encountered: