https://kotlinlang.org logo
#announcements
Title
# announcements
t

thiagoretondar

07/18/2019, 12:35 PM
What’s the best approach to call a method after all
Jobs
stored in a
List<Job>
are completed?
s

streetsofboston

07/18/2019, 12:45 PM
Iterate over the list of Jobs, call join() on each Job. Then call your method after that.
Or launch all your Coroutines (Jobs) within a
coroutineScope{ ...}
(notice the lowercase 'c'). The call to coroutineScope suspends and only resumes after all it's child Coroutines (Jobs) have completed.
t

thiagoretondar

07/18/2019, 1:01 PM
I can’t use
coroutineScope
because I need the method who invoked those
jobs
returns asap. My method is like this:
Copy code
fun process(): UUID {
    // get a list of things to do
    val listOfThings = listOf<Any>()

    val jobs = listOfThings.map { thing ->
        GlobalScope.launch {
            doProcess(thing) // suspended function
        }
    }

    // when all jobs are completed, do other thing

    return UUID.randomUUID()
}
I want
return UUID.randomUUID()
asap but before it, I want to “schedule” a method to be called after all jobs are completed
s

streetsofboston

07/18/2019, 1:21 PM
Ah! Schedule it. I see. Still, you can do what I suggested, but wrap it all up inside a
CoroutineScope.launch
call, which will return immediately.
👍🏻 1
k

kevinherron

07/18/2019, 1:33 PM
runBlocking { jobs.forEach { it.join() } }
t

thiagoretondar

07/18/2019, 2:19 PM
runBlocking
won’t work for me. I will do it with
CoroutineScope.launch
. Thanks!
a

Alexjok

07/18/2019, 2:20 PM
Copy code
fun process(): UUID = runBlocking {
    // get a list of things to do
    val listOfThings = listOf<Any>()

    val jobs = listOfThings
						.map { thing -> launch { doProcess(thing) } }
						.joinAll()

    // when all jobs are completed, do other thing

    return@runBlocking UUID.randomUUID()
}
or use coroutineScope { } instead runBlocking {}
s

streetsofboston

07/18/2019, 2:24 PM
@thiagoretondar Be careful in using
GlobalScope
, though. I’m not aware about your exact use-case, but it is advised to avoid it 🙂
t

thiagoretondar

07/18/2019, 2:25 PM
why? what should be used instead?
a

Alexjok

07/18/2019, 2:25 PM
check my sample
s

streetsofboston

07/18/2019, 2:31 PM
@thiagoretondar Either make
process
and extension function on a CoroutineScope:
fun CoroutineScope.process()
. This allows structured concurrency, especially cancelling the entire ‘process()’ request when the calling/interested party is no longer interested and canceling the entire thing (through calling the
CoroutineScope.cancel()
) If the
process
method is part of a class with its own lifecycle and needs to run as long as instances of that class are active, create a
CoroutineScope
for that and use that one for use in the
process()
function.
3 Views