Skip to content

Latest commit

 

History

History

ion-kotlin

Ion Kotlin Extensions - async/await

async/await allows you to write code that looks like synchronous code, but is actually run asynchronously via coroutines.

For example, if you wanted to download a list of files with async/await in Ion:

fun getFiles(files: Array<String>) = async {
    for (file in files) {
        Ion.with(context)
        .load(file)
        .asString()
        .await()
    }
}

This may look like synchronous code, but it is not. The return type of getFiles is a actually Future. The operation happens asynchronously, and only when all the files are finished downloading, will the Future's callback be called.

The code in an async block is a suspend fun, aka a coroutine.

async {
    // the code in here is a suspend fun, a coroutine.
    // execution can be suspended and resumed.
}

Inside an async block, you can use await on Futures to wait for their results.

fun getFiles(files: File) = async {
    System.out.println("Bob")

    val string = Ion.with(context)
    .load(file)
    .asString()
    .await()
    
    System.out.println("Chuck")
}

System.out.println("Alice")
getFiles(file)
System.out.println("David")

async blocks are run asynchronously, but look synchronous. The output from this code would be:

Alice
Bob
David
Chuck

Execution was paused at the await() call, and resumed after the file was downloaded.

Await can also be used to switch thread affinities:

async {
    looper.await()
    System.out.println("I'm running on this Looper thread.")

    handler.await()
    System.out.println("I'm running on this handler's Looper thread.")

    executor.await()
    System.out.println("I'm running on this Executor's thread pool.")
    
    asyncServer.await()
    System.out.println("I'm running on this AsyncServer's reactor thread.")
}

Getting results from async functions

async lets you easily write functions that return Futures.

fun myStringFunction(url: String) = async {
    try {
        return@async Ion.with(context)
                .load(url)
                .asString()
                .await()
    }
    catch (e: Exception) {
        return@async "Failed to load"
    }
}

myStringFunction returns a Future. Can attach setCallback to get the result, or use it in other async code blocks

Or for brevity:

fun myStringFunction(url: String) = async {
    try {
        Ion.with(context)
                .load(url)
                .asString()
                .await()
    }
    catch (e: Exception) {
        "Failed to load"
    }
}