我想问一下是否可以从函数中"返回"一个值 如果函数执行异步任务?
例如:
fun readData() : Int{
val num = 1;
doAsync {
for (item in 1..1000000){
num += 1;
}
}
return num;
}
这个函数的问题是 AsyncTask 还没有完成,所以我从函数中得到了一个错误的值,知道如何解决它吗?
使用接口是唯一的原因,或者有一个像 Swift 中的编译处理程序?
如果异步执行某些计算,则无法直接返回该值,因为您不知道计算是否已完成。您可以等待它完成,但这会使函数再次同步。相反,您应该使用回调:
fun readData(callback: (Int) -> Unit) {
val num = 1
doAsync {
for (item in 1..1000000){
num += 1
}
callback(num)
}
}
在呼叫现场:
readData { num -> [do something with num here] }
你也可以尝试一下 Kotlin 协程,它使异步代码看起来像常规的同步代码,但对于初学者来说可能有点复杂。(顺便说一下,你在 Kotlin 中不需要分号。
不仅在kotlin
中,这在任何编程语言to return from a async method
中都是不可能的。但你能做的是:
- 像克里斯蒂安建议的那样使用
co-routines
。 - 使用像
RxJava or RxKotlin
这样的反应式方法并处理数据流,即使您无法从不同线程中的方法返回,您也可以观察来自不同线程的函数返回类型。 - 如果你正在做非常简单的事情,
Callbacks
可能会有所帮助。
Kotlin 的协程绝对是你最好的选择。我从未真正尝试过,但是在异步任务中使用协程允许您从协程中返回任务中的值。我将尝试提出一个代码块来演示
就这样做:
fun readData() : Int{
val num = 1;
for (item in 1..1000000){
num += 1;
}
return num
}
val scope = CoroutineScope(Dispatchers.Main)
scope.launch{
async(Dispatchers.IO){
readData()
}.await()
}
通过异步块的替代方法,使用这样的上下文也应该工作:
fun readData() : Int{
val num = 1;
for (item in 1..1000000){
num += 1;
}
return num
}
val scope = CoroutineScope(Dispatchers.Main)
scope.launch {
withContext(Dispatchers.IO) { readData() }
然后在其他地方创建一个 courtine 来异步运行这个东西: