Launch vs Async in Kotlin: Key Differences and Usage
launch starts a coroutine that runs independently and returns a Job, while async starts a coroutine that returns a Deferred result which you can await to get a value. Use launch for tasks that don't return a result and async when you need a result from the coroutine.Quick Comparison
This table summarizes the main differences between launch and async in Kotlin coroutines.
| Factor | launch | async |
|---|---|---|
| Return Type | Job | Deferred<T> |
| Purpose | Run coroutine without result | Run coroutine with result |
| Result Access | No direct result | Use await() to get result |
| Error Handling | Propagates exceptions immediately | Exceptions thrown on await() |
| Use Case | Fire-and-forget tasks | Concurrent computations with results |
Key Differences
launch is used to start a coroutine that performs work but does not return a value. It returns a Job object that can be used to manage the coroutine's lifecycle, like cancelling it or checking if it is active.
On the other hand, async starts a coroutine that produces a result. It returns a Deferred object, which is a Job with a future result. You can call await() on this Deferred to get the result once the coroutine completes.
Exception handling also differs: with launch, exceptions are thrown immediately and can be caught by a CoroutineExceptionHandler, while with async, exceptions are deferred until await() is called, allowing you to handle errors when you consume the result.
Code Comparison
Here is an example using launch to run a coroutine that prints a message after a delay.
import kotlinx.coroutines.* fun main() = runBlocking { val job = launch { delay(500L) println("Task from launch") } println("Before joining launch") job.join() // Wait for launch coroutine to finish println("After joining launch") }
Async Equivalent
This example uses async to start a coroutine that returns a result after a delay, which is then awaited.
import kotlinx.coroutines.* fun main() = runBlocking { val deferred = async { delay(500L) "Result from async" } println("Before awaiting async") val result = deferred.await() // Wait and get result println(result) println("After awaiting async") }
When to Use Which
Choose launch when you want to start a coroutine for side effects or background work that does not produce a result you need to use later, like logging or updating UI.
Choose async when you need to perform concurrent computations that produce a result you want to use, such as fetching data or calculating a value asynchronously.
Remember, async is useful for parallelizing tasks and combining their results, while launch is simpler for fire-and-forget operations.
Key Takeaways
launch starts a coroutine without returning a result, returning a Job.async starts a coroutine that returns a result via a Deferred which you await.launch for fire-and-forget tasks and async for concurrent tasks needing results.launch throws immediately, async throws on await.Job from launch or Deferred from async.