Skip to content
Table of contents
Coroutine Launch vs Async

Coroutine Launch vs Async

1 min read #kotlin / #asynchronous / #coroutine

If you are new to coroutine or looking for the continuation, you could start from the previous article.

In this article, we will look at launch and async for making network requests.

Network Request using launch

We could use launch for network request in both sequentially and concurrently.

For sequentially,

For concurrently,

fun performNetworkRequestsConcurrently() = runBlocking<Unit> {
    launch {
        val result1 = networkCall(1)
    }

    launch {
        val result2 = networkCall(2)
    }
}

suspend fun networkCall(number: Int): String {
    delay(500)
    return "Result $number"
}
kotlin

The above code runs the network calls in parallel. However, those results are not accessible outside launch coroutine since the return for launch is a Job.

To access both results, we will need to use join() and a shared mutable state.

Although it works in above code, resultList is a shared mutable state. A general rule in concurrent programming is to avoid shared mutable state whenever possible.

Difference between launch and async

launch returns Job. async{} returns Deferred (Job with Result).

Using async, the same functionality could be achieved without a shared mutable state.

We could also add optional parameter to async(start = CoroutineStart.LAZY) and change to deferred1.start() to start lazily.

Let’s try a little different using async to reflect some UI states. We will having Loading as well as Error.

Using awaitAll for all the Deferred objects, we could make our code works. But if we do not know the exact number of network requests?

Sequential unknown network requests

Imagine if we do not know the exact number of network requests and we want to make them run in sequential.

Concurrent unknown network requests

What about concurrent style if we do not know the exact number of network requests?

Conclusion

Making network requests are often the usecase for coroutine and we look into it using launch and async. We also demonstrates sequential and concurrent request handling, highlighting the differences between the two approaches.

While launch will return Job, the use of async to obtain Deferred with wrapped results, simplifying result access.

We also explores handling both known and unknown sequential and concurrent network requests, emphasizing the flexibility and efficiency of coroutines in managing such scenarios. We hope this article provides a valuable understanding of how coroutines can effectively handle diverse network request scenarios.

Next, we will look into some useful higher-order functions from coroutine.