8

Kotlin_version = '1.2.41'

I am pretty new to Kotlin. I would like to know what's the difference between async and launch. Especially in the following code

import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.awaitAll
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>) {
    runBlocking {
        (20..30).forEach {
            launch{
                println("main before" + it)
                val outer = it
                delay(1000L)
                val lists = (1..10)
                        .map { async{anotherMethod(outer, it)}}
                println("main after------------------Awaiting" + it)
                lists.awaitAll()
                println("Done awaiting -main after-----------------" + it)

            }


        }

        println("Hello,") // main thread continues here immediately
    }
}

.

suspend fun anotherMethod (outer: Int,index: Int){
    println("inner-b4----" + outer + "--" + index)
    delay(3000L)
    println("inner-After----" + outer + "--" + index)
}

Vs

fun main(args: Array<String>) {
    runBlocking {
        (20..30).forEach {
            async{
                println("main before" + it)
                val outer = it
                delay(1000L)
                val lists = (1..10)
                        .map { async{anotherMethod(outer, it)}}
                println("main after------------------Awaiting" + it)
                lists.awaitAll()
                println("Done awaiting -main after-----------------" + it)

            }


        }

        println("Hello,") // main thread continues here immediately
    }
}

suspend fun anotherMethod (outer: Int,index: Int){
    println("inner-b4----" + outer + "--" + index)
    delay(3000L)
    println("inner-After----" + outer + "--" + index)
}
so-random-dude
  • 15,277
  • 10
  • 68
  • 113

2 Answers2

10

async does return a Deferred<>, while launch does only return a Job, both start a new coroutine. So it depends if you require a return value or not.

In your first example the launch does not return a value - the last println only produces an Unit. If you use async as in the second example, the overall result will be the same, but you create some useless Deferred<Unit> objects.

Rene
  • 5,730
  • 17
  • 20
  • Thanks for the explanation. Yes, I am getting it now :) – so-random-dude Oct 15 '18 at 16:46
  • 1
    There's also difference in exception handling. `async` is safer to use - if anything inside the block throws an exception, You will receive it in the result. However exceptions in `launch` will be re-thrown (by default) and crash your application. – Pawel Oct 15 '18 at 19:08
  • 2
    Make sure not to take the above as advice to use `async` instead of `launch`. You can provide an exception handler to `launch` to make it safe. – Marko Topolnik Oct 15 '18 at 20:19
0

launch is used to fire and forget coroutine. It is like starting a new thread. If the code inside the launch terminates with exception, then it is treated like uncaught exception in a thread -- usually printed to stderr in backend JVM applications and crashes Android applications. join is used to wait for completion of the launched coroutine and it does not propagate its exception. However, a crashed child coroutine cancels its parent with the corresponding exception, too.

async is used to start a coroutine that computes some result. The result is represented by an instance of Deferred and you must use await on it. An uncaught exception inside the async code is stored inside the resulting Deferred and is not delivered anywhere else, it will get silently dropped unless processed. You MUST NOT forget about the coroutine you’ve started with async.

Mahmoud Zaher
  • 559
  • 6
  • 6