我需要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
来自调用位置。
答案 0 :(得分:4)
不可能在原始线程上运行协程。至少必须将现有线程转换为可旋转顶级事件循环的线程。您可以通过在线程的调用堆栈的顶部(即,在其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
有一个非常特定的目的,它不是像其他语言那样的通用工具。其目的是严格并行分解,将单个任务分解为多个并发子任务。