Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Kotlin中返回等待的值?_Kotlin_Async Await_Kotlin Coroutines - Fatal编程技术网

如何在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协同程序稍微重构我的代码,但一旦我有了答案,我会回复你的答案。大概一天左右吧。