kotlin - 如何等待函数调用?

标签 kotlin kotlin-coroutines

因此,我发生了一些异步操作,可以创建一些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)
}

因此,我确实知道可以使用回调进行处理,但是以这种方式进行清理会更容易些。

我希望有一个不错的干净的解决方案,我只是想念。

最佳答案

实际上,您的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()
    

    关于kotlin - 如何等待函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59008877/

    相关文章:

    java - 有没有办法在测试之间停止 micronaut 计划的工作?

    java - Spring 启动: Set hibernate sequence globally

    android - 是否可以将变量传递给枚举?

    kotlin - 为什么 withContext 等待子协程的完成

    android - 从 Firebase 检索数据时协程流错误

    generics - 不满意 : inferred type T? 不是 Any 的子类型

    android - Retrofit2:如何从响应中保存 cookie

    kotlin - 修改延迟结果

    asynchronous - Kotlin协程中的launch/join和async/await有什么区别

    android - 如何增加 Android 上的 Kotlin 协程 Dispatchers.IO 大小?