# Experimenting with Kotlin Coroutines

As I mentioned [previously](https://blog.jlo.fail/issue-with-kotlin-scratch-files-in-intellij-idea), I've started on a new project that uses Kotlin heavily. I don't have extensive experience with Kotlin yet, but I'm learning a lot and love it. I recently needed to submit multiple HTTP requests concurrently. There were a few examples in the codebase that I had come across, but I never had the need to dig deeper. The existing code used [Kotlin Coroutines](https://kotlinlang.org/docs/coroutines-overview.html). I'm familiar with Threads in Java and concurrent programming&mdash;I've even done a side project using [Ratpack](https://ratpack.io/)&mdash;but Kotlin Coroutines were fairly new to me.

Real quick, for those that don't know, Kotlin Coroutines allow one to create asynchronous programs in a fluent way; they can be thought of as light-weight threads. 
The existing code looked something like this (simplified for clarity and to protect the innocent):

```kotlin
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope

suspend fun fetch(): MyClass =
    coroutineScope {
        val data1 = async { fetchData1() }
        val data2 = async { fetchData2() }
        MyClass(data1.await(), data2.await())
    }
```

What I needed was something similar, but my use case didn't require returning a result. I needed to fetch a result containing a list of values, and submit a request for each item concurrently without waiting for a result, but wait for all requests to finish. I searched the internet for simple examples, but almost everything was too long or confusing. And in my opinion, the best way to learn something new is to just play around with it.

So I created a simple Kotlin [Scratch file](https://www.jetbrains.com/help/idea/scratches.html) in IntelliJ Idea to experiment. I'm including a screenshot below so you can see the output side-by-side, which should make it easier to understand. See this [gist](https://gist.github.com/jlorenzen/fd59f692bc5e6e710490f36498d016ac#file-kotlin-coroutine-scratch-kt) if you want to copy the code and play around with it in Idea. Note this will require you add the necessary kotlinx.coroutine [dependencies](https://github.com/Kotlin/kotlinx.coroutines#using-in-your-projects) and make them available on your scratch file's classpath. Or if you want to play around with it online, I also copied the code to [Kotlin's Playground](https://pl.kotl.in/9RQEeYzso).

![Screen Shot 2022-04-20 at 11.15.11 AM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1650471325860/a6gtkrl3v.png)

A few things I learned about Kotlin Coroutines:

1. Use `launch` when you don't need to return a result. Also, `launch` returns an instance of `Job` which allows you to call `join` if you do need to wait till it completes. Or use something like `listOf(job1, job2).joinAll()` if you need to explicitly wait for all jobs to complete.
2. Use `async` when you do need to return a result. It returns an instance of `Deferred`, which extends `Job`. You can call the `await` function when you need to wait till it completes.
3. Calling `launch`/`async` will start that coroutine concurrently immediately; no need to call a `start` method or anything, like you have to do with a Java Thread.
4. All the jobs will be complete by the time the program exits `coroutineScope` or `runBlocking`. This was one of my biggest questions: did I have to explicitly call `join`/`await` to ensure all jobs were complete before returning from my function? And the answer is no. For example, notice in my scratch's output the `finished` statement is last and isn't emitted until all the jobs are complete. This makes sense since I am calling `runBlocking`, but I assume the same is true when using `coroutineScope` and that aligns with the Kotlin docs for [coroutineScope](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/coroutine-scope.html) (which to me were initially confusing).

Anyways, I feel a little more knowledgeable about Kotlin Coroutines. Still a ton more to learn, but that will come with time. Hope it helps someone else.
