如何在Kotlin中返回等待的值?
我需要如何在Kotlin中返回等待的值?,kotlin,async-await,kotlin-coroutines,Kotlin,Async Await,Kotlin Coroutines,我需要test()从数据库返回播放器。我知道我可以使用回调,但如何使用asyncawait fun test(): Player { launch(UI) { val player = async(CommonPool) { MainActivity.database?.playerDao()!!.loadPlayer() }.await() return player } } 当前错误为此处不允许返回 例如,在JavaScript中,我会使测试
test()
从数据库返回播放器。我知道我可以使用回调,但如何使用async
await
fun test(): Player {
launch(UI) {
val player = async(CommonPool) { MainActivity.database?.playerDao()!!.loadPlayer() }.await()
return player
}
}
当前错误为此处不允许返回
例如,在JavaScript
中,我会使测试异步然后等待它是从调用它的地方得到的结果。不可能在原始线程上运行协程。至少必须将现有线程转换为旋转顶级事件循环的线程。您可以通过在线程调用堆栈的最顶端(即在其run()
方法中)调用runBlocking
来实现这一点
在GUI线程或运行事件循环的任何其他类型的线程上,您需要一个匹配的Dispatcher
,它将协同路由提交到此事件循环。Kotlin已经为Swing、JavaFX、Android等提供了dispatchers。在这些情况下,您需要从一些现有GUI事件处理程序启动协同程序,如下所示:
myScope.launch {
val player = test()
... use the player ...
}
override val coroutineContext = Dispatchers.Main + SupervisorJob()
myScope
必须是一个对象,该对象实现了CoroutineScope
,如下所示:
myScope.launch {
val player = test()
... use the player ...
}
override val coroutineContext = Dispatchers.Main + SupervisorJob()
这将为您提供一种方法,通过调用
coroutineContext[Job]!!.cancel()
我的示例使用Main
dispatcher,当您导入与您的UI框架匹配的Kotlin协程库时,它将解析为GUI线程
test()
函数必须成为一个suspend fun
,用于临时将调度程序切换到线程池以进行阻塞操作。下面是一个基本示例的外观:
suspend fun test() = withContext(Dispatchers.IO) {
MainActivity.database?.playerDao()!!.loadPlayer()
}
最后,请注意,我在这个答案中根本没有提到async
。Kotlin的async
有一个非常特殊的用途,它不像其他语言那样是一个通用工具。它的目的是严格的并行分解,将单个任务分解为多个并发子任务。不可能在原始线程上运行协同程序。至少必须将现有线程转换为旋转顶级事件循环的线程。您可以通过在线程调用堆栈的最顶端(即在其run()
方法中)调用runBlocking
来实现这一点
在GUI线程或运行事件循环的任何其他类型的线程上,您需要一个匹配的Dispatcher
,它将协同路由提交到此事件循环。Kotlin已经为Swing、JavaFX、Android等提供了dispatchers。在这些情况下,您需要从一些现有GUI事件处理程序启动协同程序,如下所示:
myScope.launch {
val player = test()
... use the player ...
}
override val coroutineContext = Dispatchers.Main + SupervisorJob()
myScope
必须是一个对象,该对象实现了CoroutineScope
,如下所示:
myScope.launch {
val player = test()
... use the player ...
}
override val coroutineContext = Dispatchers.Main + SupervisorJob()
这将为您提供一种方法,通过调用
coroutineContext[Job]!!.cancel()
我的示例使用Main
dispatcher,当您导入与您的UI框架匹配的Kotlin协程库时,它将解析为GUI线程
test()
函数必须成为一个suspend fun
,用于临时将调度程序切换到线程池以进行阻塞操作。下面是一个基本示例的外观:
suspend fun test() = withContext(Dispatchers.IO) {
MainActivity.database?.playerDao()!!.loadPlayer()
}
最后,请注意,我在这个答案中根本没有提到async
。Kotlin的async
有一个非常特殊的用途,它不像其他语言那样是一个通用工具。它的目的是严格的并行分解,您可以将单个任务分解为多个并发子任务。使用return@launch播放器
;但是请记住,您必须等待启动从方法本身返回<代码>启动
是async@Zoe谢谢,但现在它说,类型不匹配所需的单位找到了玩家
Nvm然后。Launch可能不支持返回值。此外,当您像那样启动async时,如果不阻塞线程,就无法从方法返回。您可以使用runBlocking
而不是launch
@Zoe-Yep。这就是汇编。我要试试,不要让它堵住线;如果在主线程上使用它,请小心,否则操作系统可能会认为它超时。请尝试使用return@launch播放器
;但是请记住,您必须等待启动从方法本身返回<代码>启动
是async@Zoe谢谢,但现在它说,类型不匹配所需的单位找到了玩家
Nvm然后。Launch可能不支持返回值。此外,当您像那样启动async时,如果不阻塞线程,就无法从方法返回。您可以使用runBlocking
而不是launch
@Zoe-Yep。这就是汇编。我要试试,不要让它堵住线;如果在主线程上使用它,请小心,否则操作系统可能会认为它超时。谢谢。是不是Kotlin新增了调度员
,因为我有1.2.61
,并且得到了未解决的参考
是的,这个答案使用了官方的协程API.Sweet。我会升级并接受你的建议。我稍后会回到这里,如果答案对我有帮助的话,我会把它标记为正确的。事实证明,我需要为1.3.0协同程序稍微重构我的代码,但一旦我有了答案,我会回复你的答案。大概一天左右吧,谢谢。是不是Kotlin新增了调度员
,因为我有1.2.61
,并且得到了未解决的参考
是的,这个答案使用了官方的协程API.Sweet。我会升级并接受你的建议。我稍后会回到这里,如果答案对我有帮助的话,我会把它标记为正确的。事实证明,我需要为1.3.0协同程序稍微重构我的代码,但一旦我有了答案,我会回复你的答案。大概一天左右吧。