how would I do something like ```val myScreenState...
# coroutines
h
how would I do something like
Copy code
val myScreenState = flow<ScreenState> { 
    val newsAsync = async { newsRepository.getNews() }
    val headlinesAsync = async { newsRepository.getHeadlines() }
    emit(ScreenState(news = newsAsync.await(), headlines = headlinesAsync.await()))
}.stateIn(
    viewModelScope,
    SharingStarted.WhileSubscribed(CommonConstants.COLLECT_TIMEOUT),
    ScreenState()
)
I want to achieve parallelism, but async can’t be used since it needs a scope and inside a ViewModel I have access to the
viewModelScope
but it can’t be used in the flow builder
1
s
If you swap your flow for a channelFlow, you'll have access to a coroutine scope inside it
Or you can just use a coroutineScope block, assuming you don't need to emit values from inside your new coroutines
h
Thanks Sam, i’m assuming since using the
coroutineScope
it returns a result, after it does return everything I emit the value and it’s still possible to emit it while in the
coroutineScope
but I guess it’s not a good practice or if i need to emit something to a different flow/state flow? Where as with the
channelFlow
I can just use send to the channel 1.
coroutineScope
Copy code
val myScreenState = flow<ScreenState> {
    val screenState = coroutineScope {
        val newsAsync = async { newsRepository.getNews() }
        val headlinesAsync = async { newsRepository.getHeadlines() }
        ScreenState(news = newsAsync.await(), headlines = headlinesAsync.await())
    }
    emit(screenState)
}.stateIn(
    viewModelScope,
    SharingStarted.WhileSubscribed(CommonConstants.COLLECT_TIMEOUT),
    ScreenState()
)
2.
channelFlow
Copy code
val myScreenState = channelFlow<ScreenState> {
    val newsAsync = async { newsRepository.getNews() }
    val headlinesAsync = async { newsRepository.getHeadlines() }
    send(ScreenState(news = newsAsync.await(), headlines = headlinesAsync.await()))
}.stateIn(
    viewModelScope,
    SharingStarted.WhileSubscribed(CommonConstants.COLLECT_TIMEOUT),
    ScreenState()
)
i’m trying to understand what’s the difference and which use-case makes sense to use and when 🤔
s
Looks like for what you need,
coroutineScope
is sufficient. The
channelFlow
is needed if you want to emit (well, send) values from inside the
async
(or
launch
) subtask.
thank you color 1
h
Yes that’ll be it, thanks, is the
coroutineScope
managed or I need to manage it’s lifecycle, my question is, after it returns the value, is it still active?
s
It's all taken care of for you, the scope ends when its code and all its child coroutines are completed 👍
thank you color 1
h
And does it make sense to use
supervisorScope
or just use
coroutineScope
let’s say that the the error handling is handled by the useCase/repository
s
In this case, it doesn't make a huge difference which one you use. The
coroutineScope
function itself will throw an error if one of the child tasks fails. If you swapped it for a supervisor scope, the scope itself wouldn't throw anything, but the subsequent call to
await
would throw, so it amounts to much the same thing. I'd stick with
coroutineScope
since it will automatically cancel remaining tasks as soon as one fails, making the failure handling more prompt
🙌 2