Sequential_coroutines_FAQ
# coroutines
u
Sequential_coroutines_FAQ
d
Yes
j
The rule of thumb is that code like this:
Copy code
doSomething1()
doSomething2()
guarantees that
doSomething1()
will have returned before you can call
doSomething2()
. The meaning of "returned" is unambiguous, but the conclusions you can draw from it obviously depends on what the function does before returning. If the function has side-effects that include spawning asynchronous computations, the fact that it returns doesn't guarantee much. But in general it makes sense to the reader this way. In your example, you explicitly ruled out those particular kinds of side effects in the definition of those functions, so they are "nicely behaved" in a way. Given that, and the provided code, you can conclude that
proceedWithDoingSomething
will launch a single coroutine that runs
doSomething1
and then
doSomething2
. So they are nicely sequential.
proceedWithDoingSomethingAlternative
is different because it spawns 2 different coroutines. Those 2 coroutines run concurrently. That's the point of
launch
. This means that their execution order can be of different shapes depending on the dispatcher used to run them. They could run in parallel, or they could interlace in ways that are defined by their suspension points. That second possibility could even mean that an entire coroutine could run before the other one, and this will happen if there are no suspension points in the coroutine. If
doSomething1
has code that contains suspension points (calls to suspend functions), then by default it will "yield" the thread to the dispatcher at those points, and the dispatcher can then schedule this coroutine again or another one (potentially the one that runs
doSomething2
). If you're using a classic single-threaded dispatcher, you will usually see a fair interlacing of coroutines execution. Some dispatchers could behave differently though.
💯 1
🙏 1
Also note that even with a single-threaded dispatcher, you don't have a guarantee that the first coroutine will run first (it depends on the exact dispatcher implementation). You just know that only one will be running at a time.
👍 1
u
@Joffrey, thanks for your clear answers! does your second comments apply mostly to
proceedWithDoingSomethingAlternative()
?
j
Yes, sorry if that was unclear. That comment was about the dispatcher being able to choose how to schedule the 2 coroutines. But in
proceedWithDoingSomething
there is only one, so it's guaranteed anyway
Also, FYI
viewModelScope
uses
Dispatchers.Main.immediate
by default if I'm not mistaken, so in that case the coroutines are dispatched immediately when
launch
is called, and thus you are guaranteed that the first coroutine starts first (at least that's my understanding of this Android-provided dispatcher)
u
@Joffrey, yes, you’re right:
n
By careful with
Dispatchers.Main.immediate
, it only avoids dispatch at the top level. Nested calls to
launch
or
async
will be posted. This is done to avoid stack overflow.
👍 1