Kotlin 如何等待函数调用?

Kotlin 如何等待函数调用?,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,所以我有一些异步操作发生,我可以创建一些lambada,调用一个函数,并将该值传递给它们。但是我想要的不是将操作的结果作为参数,而是返回它们 例如,我有一个包含一些侦听器的类a,如果有结果,则通知所有侦听器。因此,如果有一个结果被挂起,asyncFunction基本上应该返回一个结果 object A { val listeners = mutableListOf<(Int) -> Unit>() fun onResult(value: Int) {

所以我有一些异步操作发生,我可以创建一些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
    }
}
所以我确实知道,通过回调,这是可以处理的,但这样做会更干净、更容易


我希望我缺少一个好的、干净的解决方案。

您的
异步函数实际上应该是一个可挂起的函数:

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()
对象A{
val result=CompletableDeferred()
乐趣提供者结果(r:Int){
结果。完成(r)
}
}
suspend fun suspendFunction():Int=A.result.await()

您的
异步函数实际上应该是一个可挂起的函数:

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()
对象A{
val result=CompletableDeferred()
乐趣提供者结果(r:Int){
结果。完成(r)
}
}
suspend fun suspendFunction():Int=A.result.await()

corroutines是为了使您不需要回调,我建议您使用通道或流而不是回调。我在考虑这个问题,但这意味着我在asyncFunction()中创建了一个cannel()将其传递给类a,然后将值放入cannel中,我只接收cannel的第一个值。如果你知道我的意思,我想要一个只针对一个物体的通道。或者,如果可能的话,我应该这样使用渠道吗?你创建一个生产者,然后创建你想要的消费者数量以及你想要他们的位置。制定了协同计划,这样你就不需要回调,我建议您使用通道或流而不是回调。我在考虑这个问题,但这意味着我在asyncFunction()中创建了一个通道,将其传递给类a,然后将值放入通道中,我只接收通道的第一个值。如果你知道我的意思,我想要一个只针对一个物体的通道。或者,如果可能的话,我应该这样使用渠道吗?你创建一个生产者,然后创建你想要的消费者数量和你想要他们的地方。