Coroutines are a way to handle multithreading in Kotlin, read more about it from the official docs:

https://kotlinlang.org/docs/coroutines-overview.html

An example of a Coroutine in Kotlin

1
2
3
4
5
6
7
8
9
val runBlocking = runBlocking {
  sleep(5)
  delay(1_000L)
  launch {
    delay(1_100L)
    note("inside launch")
  }
  note("outside launch")
}

Introducing the suspend keyword

coroutineScopes need to be in wrapping suspend:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
suspend fun coroutineFunction(): String {
  return coroutineScope {
    launch {
      println("test")
    }
    "we return this string"
  }
}

runBlocking { println(coroutineFunction()) }

Making Asynchronous API calls using Coroutines

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
suspend fun call2Apis() {
  val call1 = async {
    delay(1_000L)
    println("got data from api1 @ ${Instant.now()}")
    "some data from api1"
  }
  val call2 = async P
    delay(1_500L)
    println("got data from api2 @ ${Instant.now()}")
    "some data from api2"
  }

  println(call1.await() + " ${Instant.now()}")
  println(call2.await() + " ${Instant.now()}")

}

runBlocking { call2Apis() }
sleep(2)

Sharing states between Coroutines

Simply return a coroutineScope.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
suspend fun call2Apis() {
  return coroutineScope {
    val call1 = async {
      delay(1_000L)
      println("got data from api1 @ ${Instant.now()}")
      "some data from api1"
    }
    val call2 = async P
      println(call1.isCompleted) // false
      println(call1.await()) // pause and wait for call1 to complete..
      delay(1_500L)
      println("got data from api2 @ ${Instant.now()}")
      "some data from api2"
    }

    println(call1.await() + " ${Instant.now()}")
    println(call2.await() + " ${Instant.now()}")

  }
}

runBlocking { call2Apis() }
sleep(2)

Run tasks as Global Scope

1
2
3
4
5
runBlocking {
  GlobalScope.launch {
    //
  }
}