doesn't "Global.async{}" do the same things that "Global.launch{}" does and more? If yes, then why did they invent "Global.launch{}"? please provide a solid situation if possible.
I already searched a lot, but didn't find a convincing answer.
CodePudding user response:
To address the obvious difference: async
coroutines can return a value, whereas launch
coroutines can't. I guess you know this, and are asking if launch
does anything that can't be done with an async
coroutine that returns Unit
.
The primary difference between async
and launch
is the way they handle errors when launched as root coroutines. A root coroutine is a coroutine that is launched directly in a root scope, rather than as a child of an existing coroutine.
When you create a root coroutine with launch
, exceptions are propagated to the scope's UncaughtExceptionHandler
, if it has one. This is because the error would otherwise be lost. The job doesn't return a result, so there's nowhere else in the code that would be able to handle the error.
However, when you create a root coroutine with async
, exceptions are caught and contained in the resulting Deferred
object. The exception is thrown when you call await
. It doesn't propagate to the UncaughtExceptionHandler
. This is because we expect that some other code will eventually await
the result of the job and handle the error.
This distinction only applies to root coroutines. When you start a coroutine as a child of an existing coroutine, errors are always propagated to the parent job, regardless of whether the coroutine was started with async
or launch
.
So, to answer your question, launch
provides the additional capability to handle errors with an UncaughtExceptionHandler
when launching root coroutines.