I'm constructing a `flow { }` via a bunch of `emit...
# coroutines
r
I'm constructing a
flow { }
via a bunch of
emit()
. Is there a way to terminate said flow, such that
last()
on the flow returns something?
k
I’m not sure I understand your question. Do you mind rephrasing it?
r
Can I construct a
Flow
with
flow { }
where an attached
collect { }
would terminate?
k
Yes:
Copy code
flow { emit(1) }.collect { ... }
println("Got here")
But I still expect I’m misunderstanding your question. Not every flow is infinite.
r
Ah, understood. I'm jumping to the
flow { }
via
return@flow
, which doesn't seem to terminate the flow 😅
k
Do you have a snippet?
r
Cut down on the
when
block, otherwise it's original: https://gist.github.com/reactormonk/e82c1af9a766be1370b0bc70acd10ff4
k
Strange. Might be worth making a repro with non-local returns (
return@flow
) to see if you can reproduce.
r
Erm, I should have mentioned that I'm using a
shareIn
to run the flow, does the flow termination transfer there?
... reload the snippet, I added the code there
k
Shared flows are always infinite, so no, it wouldn’t.
Shared flow never completes. A call to Flow.collect on a shared flow never completes normally, and neither does a coroutine started by the Flow.launchIn function. An active collector of a shared flow is called a subscriber.
r
Is there a language construct of a hot flow that terminates?
k
No.
And for good reason.
Why do you need this flow to be hot?
r
It's very effectful, so I wanna run it exactly once, that's why I made it hot.
Basically running two at the same time leads to very undefined behavior.
k
Rather than using a shared flow to do that work for you, you’d be better off creating some kind of wrapper that ensures only one runs at a time
Or, do something like
sharedflow.takeWhile { it != Complete }.collect()
r
Neat idea, a
filterIsInstance
even downcasts it for me.
Thanks for the help!
k
No problem