https://kotlinlang.org logo
Title
t

The Monster

01/15/2022, 2:53 PM
I want
scanAudios()
and
scanVideos()
to execute first before other stuff in this function.
private suspend fun getFolderDataList(): List<FolderData> {
        thisScope.async() {
            scanAudios()
            scanVideos()
        }.await()

        val audioFolderData = viewModel.getAudioUris().map { uri ->
            FolderData("Audio", uri)
        }

        val videoFolderData = viewModel.getVideoUris().map { uri ->
            FolderData("Video", uri)
        }

        return audioFolderData.plus(videoFolderData)
    }
Am I doing it correctly?
d

Dominaezzz

01/15/2022, 2:55 PM
Short answer is yes.
👀 1
I'm a little sceptical about the immediate
await
after the
async
, but it should do what you want.
Why have you used
async
there?
t

The Monster

01/15/2022, 2:59 PM
I needed the function
await()
.
launch()
does not have it.
launch()
only has
invokeOnCompletion()
which I cannot use because the other code are also suspend functions.
d

Dominaezzz

01/15/2022, 3:01 PM
launch
has
join
.
Why not just call
scanAudios
and
scanVideos
without wrapping it in a coroutine?
t

The Monster

01/15/2022, 3:03 PM
oh I didn't know of
join
. Let me check it out.
scanAudios
and
scanVideos
need to complete first for the code after to be accurate.
d

Dominaezzz

01/15/2022, 3:05 PM
Sure but you can do that without wrapping them.
The wrapping you've added there doesn't change anything with regards to ordering.
t

The Monster

01/15/2022, 3:06 PM
oh how do I wait for them without the
join
or
await
then?
d

Dominaezzz

01/15/2022, 3:07 PM
private suspend fun getFolderDataList(): List<FolderData> {
        scanAudios()
        scanVideos()

        val audioFolderData = viewModel.getAudioUris().map { uri ->
            FolderData("Audio", uri)
        }

        val videoFolderData = viewModel.getVideoUris().map { uri ->
            FolderData("Video", uri)
        }

        return audioFolderData.plus(videoFolderData)
    }
What do you mean by wait? What does
scanAudios
do? It's a suspend function right?
t

The Monster

01/15/2022, 3:09 PM
are you sure
getAudioUris()
and
getVideoUris()
won't be executed when `scanAudios`/`scanVideos` are running?
yes
scanAudios
is a suspend function.
getAudioUris
and
getVideoUris
are also suspend.
d

Dominaezzz

01/15/2022, 3:12 PM
Yes, suspend functions suspend the coroutine when they are called. You only get concurrency when you introduce it with
launch
or
async
.
🙌 1
1
t

The Monster

01/15/2022, 3:12 PM
wait here means I want
scanAudios
and
scanVideos
to finish first before calls to
getAudioUris
and
getVideoUris
ohh
d

Dominaezzz

01/15/2022, 3:14 PM
Do you also want scanAudios and scanVideos to run at the same time?
t

The Monster

01/15/2022, 3:14 PM
Thanks for the help. I haven't used coroutines for a while; I must have confused between concurrency and suspension.
👍🏼 1
yes I want them to run at the same time
d

Dominaezzz

01/15/2022, 3:14 PM
Ah, in that case.....
private suspend fun getFolderDataList(): List<FolderData> {
        coroutineScope {
            launch { scanAudios() }
            launch { scanVideos() }
        }

        val audioFolderData = viewModel.getAudioUris().map { uri ->
            FolderData("Audio", uri)
        }

        val videoFolderData = viewModel.getVideoUris().map { uri ->
            FolderData("Video", uri)
        }

        return audioFolderData.plus(videoFolderData)
    }
🙌 1
t

The Monster

01/15/2022, 3:16 PM
perfect. Thanks. Your code helps this part of the doc makes more sense now. https://kotlinlang.org/docs/composing-suspending-functions.html#concurrent-using-async
j

Joffrey

01/15/2022, 3:32 PM
Calling suspend functions is like regular functions, they don't return until they're done. Using
async{...}.await()
is pointless and actually equivalent to just calling the functions. The only difference here is you're using a particular scope, so the coroutine context could be different, but in terms of what waits and what doesn't it's equivalent
🙌 1
If you want to call
scanAudios
and
scanVideos
concurrently, it's another story. But it doesn't seem to be your goal here, so you can keep things very simple