所以我发生了一些异步操作,我可以创建一些lambada,调用一个函数并将该值传递给它们。但是我想要的不是将运算结果作为参数,而是要返回它们。
作为一个例子,我有一个带有一些侦听器的类A,如果有结果,将通知所有侦听器。因此,基本上asyncFunction应该返回一个结果,如果有一个结果则被挂起。
object A {
val listeners = mutableListOf<(Int) -> Unit>()
fun onResult(value: Int) {
listeners.forEach { it(value) }
}
}
fun asyncFunction(): Deferred<Int> {
return async {
A.listeners.add({ result ->
})
return result
}
}
我现在正在考虑的事情(也许我完全走错了路)是让Deferred之类的东西发送给我,然后将结果发送给它。有那样的东西吗?我可以自己实施受苦者吗?
class A {
private val awaiter: ??? // can this be a Deferred ?
fun onResult(result: Int) {
awaiter.putResult(result)
}
fun awaitResult(): Int {
return awaiter.await()
}
}
val a = A()
launch {
val result = a.awaitResult()
}
launch {
a.onResult(42)
}
所以我确实知道可以使用回调进行处理,但是这样做更干净,更容易。
我希望有一个不错,干净的解决方案,而我只是想念它。
答案 0 :(得分:3)
您的asyncFunction
实际上应该是一个可挂起的函数:
suspend fun suspendFunction(): Int =
suspendCoroutine { cont -> A.listeners.add { cont.resume(it) } }
请注意,它将返回Int
结果并暂停直到可用。
但是,这仅是解决您当前问题的方法。它仍然会在许多方面发生故障:
suspendFunction
之前到达,它将丢失并挂起。您可以继续手动进行改进(这是学习的好方法),也可以切换到标准库提供的可靠解决方案。库解决方案为CompletableDeferred
:
object A {
val result = CompletableDeferred<Int>()
fun provideResult(r: Int) {
result.complete(r)
}
}
suspend fun suspendFunction(): Int = A.result.await()