Faire appel asynchrone synchrone à Kotlin

auser:

J'ai une API que je ne contrôle pas .... qui contient une méthode qui fait un travail et renvoie les résultats de manière asynchrone. Je voudrais appeler cette méthode de manière synchrone dans certaines parties de ma demande. Je l' ai fait en ajoutant une classe ResultHandlerqui capte et renvoie le résultat. Y at - il une meilleure façon de le faire que la façon dont je l' ai fait ci - dessous? Peut-être en utilisant Kotlin standard (ou Java en dernier recours) Méthodes bibliothèque. Ma préférence serait pour awaitReplyretourner le résultat et aussi pour enlever le CountdownLatch.

class Main {
    companion object {
        @JvmStatic

        fun main(args: Array<String>) {
            val result1 = Main().nonAsyncMethod1(arrayListOf(1, 2, 3, 4, 5))
            result1.elements.forEach { println(it) }
        }
    }

    class Result1(var elements: Collection<String>)

    fun asyncMethod1(x: Collection<Int>, callback: (Result1) -> Unit) {
        Thread().run {
            // do some calculation
            Thread.sleep(1000)
            callback(Result1(x.map { "\"$it\"" }.toList()))
        }
    }

    private fun nonAsyncMethod1(entities: Collection<Int>): Result1 {
        val resultHandler = ResultHandler<Result1>()

        awaitReply<Result1> {
            asyncMethod1(entities, resultHandler)
        }
        return resultHandler.getResponse()
    }

    open class ResultHandler<T : Any> : (T) -> Unit {
        private lateinit var response: T
        private val latch = CountDownLatch(1)

        override fun invoke(response: T) {
            latch.countDown()
            this.response = response
        }

        fun getResponse(): T {
            latch.await()
            return response
        }
    }

    private fun <T : Any> awaitReply(call: () -> Unit) {
        return call.invoke()
    }
}
auser:

Merci à la pointe de the_dani

Je viens à la GÉRÉ solution ci - dessous à l' aide coroutines comme indiqué dans « callbacks d'emballage section » du Kotlin Coroutines documentation:

class Main {
    companion object {
        @JvmStatic

        fun main(args: Array<String>) = runBlocking {
            val result1 = Main().nonAsyncMethod1(arrayListOf(1, 2, 3, 4, 5))
            result1.elements.forEach { println(it) }
        }
    }

    class Result1(var elements: Collection<String>)

    fun asyncMethod1(x: Collection<Int>, callback: (Result1) -> Unit) {
        Thread().run {
            // do some calculation
            Thread.sleep(1000)
            callback(Result1(x.map { "\"$it\"" }.toList()))
        }
    }

    suspend fun nonAsyncMethod1(entities: Collection<Int>): Result1 = suspendCoroutine {
        cont ->
            asyncMethod1(entities) { cont.resume(it) }
    }
}

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=212033&siteId=1
conseillé
Classement