Stylianos Gakis
01/19/2022, 7:15 PMStylianos Gakis
01/19/2022, 7:15 PMfun getLoginStatusAsFlow(): Flow<LoginStatus> {
return callbackFlow {
val callback: (data: Any) -> Unit = { data ->
val result = someSuspendingFunction(data) //Error here, not in a suspending scope
channel.trySend(result) // Or .send
}
foo.registerCallback(callback)
awaitClose { foo.unregisterCallback(callback) }
}
}
Any ideas on how to approach this?jw
01/19/2022, 7:17 PMFlow
, map
the network call.hfhbd
01/19/2022, 7:17 PMflow.map {}
?
fun getLoginStatusAsFlow(): Flow<LoginStatus> {
return callbackFlow {
val callback: (data: Any) -> Unit = { data ->
channel.send(data) // Or .send
}
foo.registerCallback(callback)
awaitClose { foo.unregisterCallback(callback) }
}.map {data ->
someSuspendingFunction(data)
}
}
Casey Brooks
01/19/2022, 7:19 PMcallbackFlow
is probably fine for what you need, unless it's emitting really quickly. callbackFlow basically just sends events into a buffered Channel
(default buffer capacity of 64), and then exposes that channel as a Flow
. So like the others have said, callbackFlow { }.map { }
should be perfectly fine for this usecase, since you can post up to 64 events to get queued up and processed one-by-one from the Flow before anything bad happensStylianos Gakis
01/19/2022, 7:25 PMmap
with mapLatest
which would cancel the old request right?
I also don’t quite care for storing older triggers, would then removing the default buffer capacity be a smart idea, with something like .conflate()
right before the map?
Thanks a lot for all the suggestions and help btw, really appreciated!Nick Allen
01/19/2022, 8:16 PMmapLatest
. conflate
only affects behavior if items are sent faster than they are collected. mapLatest
cancels on new events so the upstream rarely runs into this. Not that it's impossible, cancellation and just receiving from the Channel
can take time to dispatch and finish.Stylianos Gakis
01/19/2022, 9:23 PMcallbackFlow
callback sends a lot of values, while I’m still inside the mapLatest
and I’m pending cancellation, I don’t want all the incoming value to wait in queue and go into the mapLatest
only to be cancelled again, conflating them would simply drop the oldest events and have the latest one wait until the ongoing mapLatest
is being cancelled.
* After testing it a bit, it seems like it will enter the mapLatest
even if there are many queued things. This is problematic in the case that my mapLatest
isn’t cooperating with cancelation immediately. I can add a yield() as the first line of mapLatest
and it achieves the same goal.
But you’re right, conflating them after the mapLatest
as well would also help the observer to only receive the latest value in case it’s for some reason consuming the new values at a lower pace. Thanks for this tip as well!