```override suspend fun requestBooks(): Flow<Li...
# coroutines
c
Copy code
override suspend fun requestBooks(): Flow<List<Book>> {
  return callbackFlow {
    val listener =
        FirebaseFirestore.getInstance().collection("books").addSnapshotListener { value, error
          ->
          trySend(value!!.toObjects())
        }
    awaitClose { listener.remove() }
  }
}
How do I move the
trySend(value!!.toObjects())
to a background thread. My issue is that
value!!.toObjects()
is a deserialization operation that can take a long time. Wrapping
trySend
in a launch with Dispatchers.IO seems to help my lag issue in my app, but is it really that easy? Or am i shooting myself in the foot.
Copy code
launch(<http://Dispatchers.IO|Dispatchers.IO>) { 
  trySend(value!!.toObjects())
}
e
that has the potential of being reordered - two callbacks may result in sends in the opposite order
if that's tolerable then great, if it's not then you need a queue, which Channel itself effectively is (with appropriate buffering)
c
I believe it's tolerable yes, but just out of curiosity... I can use a queue here? Is that a just kotlin data structure, or is queue + channel some kind of flowable primitive?
e
I mean that anything
blockingSend
to a
channel
, and then collected from the
channel.collectAsFlow().buffer()
, is effectively queued
as long as the buffer isn't full (or is unlimited), you can get that with
trySend().onFailure { throw }
oh right, if you wanted to move
toObjects
to another thread though…
I believe
Copy code
callbackFlow {
    addListener { value, error ->
        trySend(value!!).onFailure { throw it }
    }
}.map { value.toObjects() }.flowOn(<http://Dispatchers.IO|Dispatchers.IO>).buffer()
would do that
c
hm. i'll play around with variations of that since that doesn't seem to compile.
e
I had to move and adjust the buffer but this should work: https://pl.kotl.in/Bx4HXwYWb