如何等待函数调用?
How To await a function call?
所以我发生了一些异步操作,我可以创建一些 lambada,调用一个函数并将该值传递给它们。但是我想要的不是把运算的结果作为参数,我要return他们
例如,我有一个 class A 和一些听众,如果有结果,所有听众都会收到通知。所以基本上 asyncFunction 应该 return 一个结果,否则会被暂停。
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 的东西,我可以将结果发送到它 returns。有类似的东西吗?我可以自己实现 Deffered 吗?
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)
}
所以我知道通过回调可以处理这个问题,但这样会更干净、更容易。
我希望我只是缺少一个漂亮干净的解决方案。
您的 asyncFunction
实际上应该是一个可挂起的函数:
suspend fun suspendFunction(): Int =
suspendCoroutine { cont -> A.listeners.add { cont.resume(it) } }
请注意,它 returns Int
结果并暂停直到它可用。
但是,这只是解决您当前问题的方法。它仍然会在很多方面出现故障:
- 一旦获得第一个结果,监听器的目的就达到了,但它永远停留在监听器列表中,导致内存泄漏
- 如果结果在您调用
suspendFunction
之前到达,它将错过并挂起。
您可以继续手动改进它(这是一种很好的学习方式),或者切换到标准库提供的可靠解决方案。库解为CompletableDeferred
:
object A {
val result = CompletableDeferred<Int>()
fun provideResult(r: Int) {
result.complete(r)
}
}
suspend fun suspendFunction(): Int = A.result.await()
所以我发生了一些异步操作,我可以创建一些 lambada,调用一个函数并将该值传递给它们。但是我想要的不是把运算的结果作为参数,我要return他们
例如,我有一个 class A 和一些听众,如果有结果,所有听众都会收到通知。所以基本上 asyncFunction 应该 return 一个结果,否则会被暂停。
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 的东西,我可以将结果发送到它 returns。有类似的东西吗?我可以自己实现 Deffered 吗?
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)
}
所以我知道通过回调可以处理这个问题,但这样会更干净、更容易。
我希望我只是缺少一个漂亮干净的解决方案。
您的 asyncFunction
实际上应该是一个可挂起的函数:
suspend fun suspendFunction(): Int =
suspendCoroutine { cont -> A.listeners.add { cont.resume(it) } }
请注意,它 returns Int
结果并暂停直到它可用。
但是,这只是解决您当前问题的方法。它仍然会在很多方面出现故障:
- 一旦获得第一个结果,监听器的目的就达到了,但它永远停留在监听器列表中,导致内存泄漏
- 如果结果在您调用
suspendFunction
之前到达,它将错过并挂起。
您可以继续手动改进它(这是一种很好的学习方式),或者切换到标准库提供的可靠解决方案。库解为CompletableDeferred
:
object A {
val result = CompletableDeferred<Int>()
fun provideResult(r: Int) {
result.complete(r)
}
}
suspend fun suspendFunction(): Int = A.result.await()