Hi all - is there a `Flow<T>.flowOn(dispatch...
# coroutines
x
Hi all - is there a
Flow<T>.flowOn(dispatcher)
equivalent that that affects downstream? so that i can do
Copy code
results
  .map { result -> format(result) }
  .flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
  .collectOn(Dispatchers.Main)
  .collect { presenter.display(it) }
instead of
Copy code
withContext(Dispatchers.Main) { 
  results
    .map { result -> format(result) }
    .flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
    .collect {
      presenter.display(it)
    }
}
s
What about:
Copy code
withContext(Dispatchers.Main) {
  results
    .map { result -> format(result) } 
    .flowon(<http://Dispatchers.IO|Dispatchers.IO>)
    .collect { ... }
}
since
collect
is a suspending function
u
scope you run in is your downstream "thread"
n
flowWith
used to exist as part of the Flow preview library but was removed because it didn't play well with other coroutine/flow semantics.
If you simply want to avoid the nesting:
Copy code
results
  .map { result -> format(result) }
  .flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
  .onEach { presenter.display(it) }
  .flowOn(Dispatchers.Main)
  .collect()
❤️ 1
x
yeah i prefer less nesting - and like @Nick Allen’s one the most
is there a negative connotation of using
.onEach
instead of
.collect
?
e
no, it's also the only reasonable way to use
.launchIn(scope)
m
If you are using it in Android ViewModel, you can use launchIn like below. (as ephemient mentioned above)
Copy code
private fun sample1() {
    membershipUiData
        .map { /* IO Thread */ }
        .flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
        .onEach { data ->
            /* Main thread */ 
        }
        .launchIn(viewModelScope)
}

private suspend fun sample2() = viewModelScope.launch {
    membershipUiData
        .map { /* IO Thread */ }
        .flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
        .collect { data ->
            /* Main thread */
        }
}
(viewModelScope is composed of Dispatchers.main.immediate + SupervisorJob. So, if you are not using ViewModel, you can define appropriate context by yourself.)
e
but consider
Copy code
viewLifecycleOwner.repeatOnLifecycle(STARTED) {
    flow.collect { ... }
}
instead, https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda