I want to execute the coroutines in the for loop i...
# coroutines
h
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
Wrap the
forEach
call inside a
coroutineScope
call.
Or change
forEach
to
map
. Then call
forEach { it.join() }
.
h
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
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
coroutineScope
should be considered as the idiomatic approach
h
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
The only thing signalling parallel work is
launch
h
yes but does not really indicate all the coroutines completion will be waited.
g
+1 for join, or even better joinAll:
Copy code
listOf(1,2,3).map { launch {} }.joinAll()
d
I do like that
joinAll()
g
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
I feel
joinAll
is like conditional goto and
coroutineScope
is like if/else. More "structure".
g
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
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
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()
   }
725 Views