Search code examples
kotlinrx-javacoroutinekotlin-coroutines

Convert RXJava Single to a coroutine's Deferred?


I have a Single from RxJava and want to continue working with a Deferred from Kotlin Coroutines. How to accomplish that?

fun convert(data: rx.Single<String>): kotlinx.coroutines.Deferred<String> = ...

I would be interested in some library (if there is any?) as well as in doing this on my own... So far I did this hand-made implementation on my own:

private fun waitForRxJavaResult(resultSingle: Single<String>): String? {
    var resultReceived = false
    var result: String? = null

    resultSingle.subscribe({
        result = it
        resultReceived = true
    }, {
        resultReceived = true
        if (!(it is NoSuchElementException))
            it.printStackTrace()
    })
    while (!resultReceived)
        Thread.sleep(20)

    return result
}

Solution

  • There is this library that integrates RxJava with Coroutines: https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2

    There's no function in that library to directly convert a single to a Deferred though. The reason for this is probably that an RxJava Single is not bound to a coroutine scope. If you want to convert it to a Deferred you would therefore need to provide it a CoroutineScope.

    You could probably implement it like this:

    fun <T> Single<T>.toDeferred(scope: CoroutineScope) = scope.async { await() }
    

    The Single.await function (used in the async-block) is from the kotlinx-coroutines-rx2 library.

    You can call the function like this:

    coroutineScope {
        val mySingle = getSingle()
        val deferred = mySingle.toDeferred(this)
    }