java在Kotlin中使异步调用同步
我有一个我无法控制的API。。。。它包含一个执行某些工作并异步返回结果的方法。我希望在应用程序的某些部分中同步调用此方法。为此,我添加了一个类ResultHandler
,该类捕获并返回结果。有没有比下面我做的更好的方法?可能使用标准kotlin(或Java作为最后手段)库方法。我的首选是awaitReply
返回结果,并删除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()
}
}
# 1 楼答案
您可以使用带有协同路由的回调来包装异步函数 (协同程序类似于C#async/await,您可以创建看起来非常同步但执行异步的异步代码)
https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md#wrapping-callbacks
挂起函数只能在协同路由上下文中调用(例如使用} ,然后它应该等待协同路由完成。这会产生你想要的行为
launch{ }
),但是为了等待,可以使用^{# 2 楼答案
多亏了丹麦人的暗示
我使用Kotlin协同程序文档的“Wrapping callbacks”部分详细介绍的协同程序实现了以下解决方案: