我需要test()
从我的数据库返回一个播放器。我知道我可以使用回调,但是如何使用async
await
进行此操作?
fun test(): Player {
launch(UI) {
val player = async(CommonPool) { MainActivity.database?.playerDao()!!.loadPlayer() }.await()
return player
}
}
当前错误是
return is not allowed here
例如,在
JavaScript
中,我将test
设为async
,然后将await
设为它的调用位置。
最佳答案
在原始线程上运行协程是不可能的。至少必须将现有线程转换为可旋转顶级事件循环的线程。您可以通过在线程调用堆栈的顶部(即,在其runBlocking
方法内部)调用run()
来实现此目的。
在GUI线程或运行事件循环的任何其他类型的线程上,您需要一个匹配的Dispatcher
来向该事件循环提交协程。 Kotlin已经为Swing,JavaFX,Android等提供了调度程序。在这些情况下,您需要使用一些现有的GUI事件处理程序对协程进行launch
编码,如下所示:
myScope.launch {
val player = test()
... use the player ...
}
myScope
必须是使用以下内容实现CoroutineScope
的对象:override val coroutineContext = Dispatchers.Main + SupervisorJob()
这将为您提供一种方法,可以通过调用来完全取消在同一范围内运行的所有协程
coroutineContext[Job]!!.cancel()
我的示例使用
Main
调度程序,当您导入与UI框架匹配的Kotlin协程库时,该调度程序解析为GUI线程。test()
函数必须成为suspend fun
,该临时将调度程序临时切换到线程池以进行阻塞操作。这是一个基本示例的外观:suspend fun test() = withContext(Dispatchers.IO) {
MainActivity.database?.playerDao()!!.loadPlayer()
}
最后,请注意,在此答案中我根本没有提到
async
。 Kotlin的async
具有非常特定的目的,它不是其他语言中的通用工具。它的目的是严格并行分解,您可以在其中将单个任务分解为多个并发子任务。
关于kotlin - 如何在Kotlin中返回等待的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53414607/