Thursday, 13 June 2019

Suspend Coroutine example

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.concurrent.thread
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

open class Result(val output: String?)

class Success(output: String) : Result(output)

class Failure : Result(null)

fun onComplete(result: Result?) {
    when (result) {
        is Success -> println("onSuccess : ${result.output}")
        is Failure -> println("onError ")
    }
}

class Callback {
    var listener: ((Result?) -> Unit)? = null
    internal fun onSuccess(result: Result?) {
        onComplete(result)
    }

    internal fun onError(result: Result?) {
        onComplete(result)
    }

    internal fun addListener(listener: ((Result?) -> Unit)?) {
        this.listener = listener
    }

    fun onComplete(result: Result?) {
        listener?.let { it(result) }    }
}

fun fakeAsyncCallback(): Callback {
    val callback = Callback()

    thread(isDaemon = false) {        try {
            println("starting fakeAsyncCallback")

            Thread.sleep(2000)

            println("done fakeAsyncCallback")

            callback.onSuccess(Success("fakeAsyncCallback completed"))
        } catch (throwable: Throwable) {
            callback.onError(Failure())
        }
    }
    return callback
}

suspend fun convertToSuspend(callback: Callback): String {
    return suspendCoroutine { continuation ->        callback.addListener { result ->            when (result) {
                is Success -> continuation.resume("onSuccess : ${result.output}")
                is Failure -> continuation.resume("onError ")
            }
        }    }}

fun main(args: Array) = runBlocking {    val callback = fakeAsyncCallback()
    val job = GlobalScope.launch {        val result = convertToSuspend(callback)
        
        println(result)
    }
    println("called fakeAsyncCallback")

    println("main done")

    job.join()
}

No comments: