Home > Software engineering >  Why do we need "GlobalScope.launch{}" when we already have "GlobalScope.async{}"
Why do we need "GlobalScope.launch{}" when we already have "GlobalScope.async{}"

Time:11-19

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.

  • Related