繁体   English   中英

如何在 SAM 中调用暂停 function?

[英]How do you call a suspend function inside a SAM?

我正在尝试创建一个需要从回调发出值的Flow ,但我不能调用emit function 因为 SAM 是普通的 function

这是 class 和库中的 SAM,我无法按照我需要的方式对其进行修改。

class ValueClass {

    fun registerListener(listener: Listener) {
        ...
    }    

    interface Listener {
        fun onNewValue(): String
    }
}

这是我对创建Flow object 的看法

class MyClass(private val valueClass: ValueClass) {
    fun listenToValue = flow<String> {
        valueClass.registerListener { value ->
            emit(value) // Suspension functions can only be called on coroutine body
        }
    }
}

我想如果我可以更改ValueClass会很简单,但在这种情况下,我不能。 我一直在思考这个问题并试图寻找实现。

至少据我所知,一种解决方案是像这样使用GlobalScope

class MyClass(private val valueClass: ValueClass) {
    fun listenToValue = flow<String> {
        valueClass.registerListener { value ->
            GlobalScope.launch {
                emit(value)
            }
        }
    }
}

现在,这可行,但我不想使用GlobalScope ,因为我将使用viewModelScope将它与我的应用程序的生命周期联系起来。

有没有办法解决这个问题?

提前致谢。 任何帮助将不胜感激!

您可以使用callbackFlow从回调中创建一个Flow 它看起来像:

fun listenToValue(): Flow<String> = callbackFlow {
    valueClass.registerListener { value ->
        trySend(value)
        channel.close() // close channel if no more values are expected
    }
    awaitClose { /*unregister listener*/ }
}

或者,如果回调中只需要一个值,您可以使用suspendCoroutinesuspendCancellableCoroutine 在这种情况下, listenToValue() function 必须suspend ,然后从协程(例如someScope.launch )中调用:

suspend fun listenToValue(): String = suspendCoroutine { continuation ->
    valueClass.registerListener { value ->
        continuation.resumeWith(value)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM