https://kotlinlang.org logo
#coroutines
Title
# coroutines
h

Hadi Tok

10/07/2018, 2:04 PM
I want to execute the coroutines in the for loop in parallel and when all complete I want
print(5)
to run. how should I go for doing this? the current code I sent runs the coroutines in loop parallel but
print(5)
does not wait for completion of the others.
d

Dominaezzz

10/07/2018, 2:09 PM
Wrap the
forEach
call inside a
coroutineScope
call.
Or change
forEach
to
map
. Then call
forEach { it.join() }
.
h

Hadi Tok

10/07/2018, 2:18 PM
both of them works. thanks a lot. I will go for the first one I think it is more self explaining when is used.
d

Daniel Tam

10/07/2018, 2:49 PM
I think the second one is more self explanatory to be honest..
join
is very explicit about what you're doing, rather than implicitly waiting for the scope to finish
d

Dico

10/07/2018, 3:31 PM
coroutineScope
should be considered as the idiomatic approach
h

Hadi Tok

10/07/2018, 3:51 PM
my concern with the second option is it is not clear where it will join when the
join()
is called. also it is not clear that the code is doing a parallel work. using
coroutineScope
gives more visibility to parallel execution.
d

Dico

10/07/2018, 3:52 PM
The only thing signalling parallel work is
launch
h

Hadi Tok

10/07/2018, 4:06 PM
yes but does not really indicate all the coroutines completion will be waited.
g

gildor

10/07/2018, 9:57 PM
+1 for join, or even better joinAll:
Copy code
listOf(1,2,3).map { launch {} }.joinAll()
d

Dico

10/07/2018, 10:03 PM
I do like that
joinAll()
g

gildor

10/07/2018, 10:13 PM
coroutineScope is new and I don't have strong opinion yet about such use case, but still joinAll looks more explicit for me than coroutineScope
d

Dominaezzz

10/07/2018, 10:27 PM
I feel
joinAll
is like conditional goto and
coroutineScope
is like if/else. More "structure".
g

gildor

10/08/2018, 1:13 AM
Not sure that I get your analogy about
goto
and
joinAll
For me joinAll looks much more explicit just because you explicitly says that you want to wait all jobs in list, very clear. In case of coroutineScope it’s implementation detail that changed one version ago.
👍 1
d

Daniel Tam

10/08/2018, 5:19 AM
Yeah I disagree that the second option is not clear. If anything,
join
and
joinAll
makes it very clear what you're trying to do.
h

Hadi Tok

10/08/2018, 7:46 AM
When I look at the code without knowing what they do I they look like they are doing the same thing between
Copy code
@Test
    fun testCoroutineOrder() = runBlocking {
        listOf(1, 2, 3, 4).forEach {
            launch {
                delay(1000)
                println(it)
            }.join()
        }
        print(5)
    }
and
Copy code
@Test
    fun testCoroutineOrder2() = runBlocking {
        listOf(1, 2, 3, 4).map {
            launch {
                delay(1000)
                println(it)
            }
        }.forEach { it.join() }
        print(5)
    }
first executes them in order but second executes them asynchronously. but
joinAll
changes the game. Probably doing the same thing as
forEach{ it.join() }
but since it is applied to the list as whole It makes more sense in the first look.
But i think
coroutineScope
(even
supervisorScope
) still needs to be kept in mind. if the coroutines are not in a list like
Copy code
coroutineScope{
      getA()
      getB()
      getC()
   }
422 Views