[英]Kotlin coroutine does not run synchronously
在我一直使用 corrutines 的所有情况下,到目前为止,它一直在同步执行它的“行”,这样我就能够在下一行代码中使用变量的结果。
我有调用服务器的 ImageRepository class,获取图像列表,一旦获得,就创建一个包含图像和相关信息的 json。
class ImageRepository {
val API_IMAGES = "https://api.MY_API_IMAGES"
suspend fun fetch (activity: AppCompatActivity) {
activity.lifecycleScope.launch() {
val imagesResponse = withContext(Dispatchers.IO) {
getRequest(API_IMAGES)
}
if (imagesResponse != null) {
val jsonWithImagesAndInfo = composeJsonWithImagesAndInfo(imagesResponse)
} else {
// TODO Warning to user
Log.e(TAG, "Error: Get request returned no response")
}
...// All the rest of code
}
}
}
嗯,suspend function 正确同步执行,它首先在 getRequest 中调用服务器,当有响应时,然后组成 JSON。到目前为止,一切顺利。
这是我的主要活动对“ImageRepository”暂停 function 的调用:
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) { neoRepository.fetch(this@MainActivity) }
Log.i(TAG, "After suspend fun")
}
问题是,一执行就调用暂停function然后显示log,明显是空的。 它不会等待暂停 function 完成,然后显示日志。
为什么? 我究竟做错了什么?
我尝试了不同的 Dispatchers 等,但没有成功。
我感谢任何帮助。
谢谢并致以最诚挚的问候。
这是因为您正在从您的暂停 function 中并行启动另一个协程。与其在那里启动另一个协程,不如直接在您的暂停 function 中调用该启动的内容。
suspend function 就像普通的 function 一样,一条一条指令执行。 唯一的区别是它可以暂停,这意味着运行时环境可以决定暂停/暂停执行以执行其他工作,然后稍后恢复执行。
这是真的,除非你开始了一个你不应该做的异步操作。 您的提取操作应如下所示:
class ImageRepository {
suspend fun fetch () {
val imagesResponse = getRequest(API_IMAGES)
if (imagesResponse != null) {
val jsonWithImagesAndInfo = composeJsonWithImagesAndInfo(imagesResponse)
} else {
// TODO Warning to user
Log.e(TAG, "Error: Get request returned no response")
}
... // All the rest of code
}
}
-> 就像常规的 function 一样。当然,您需要从协程中获取所有信息:
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) { neoRepository.fetch() }
Log.i(TAG, "After suspend fun")
}
Google 建议将调度程序注入较低级别的类 ( https://developer.android.com/kotlin/coroutines/coroutines-best-practices ) 所以理想情况下你会这样做:
val neoRepository = ImageRepository(Dispatchers.IO)
lifecycleScope.launch {
val result = neoRepository.fetch()
Log.i(TAG, "After suspend fun")
}
class ImageRepository(private val dispatcher: Dispatcher) {
suspend fun fetch () = withContext(dispatcher) {
val imagesResponse = getRequest(API_IMAGES)
if (imagesResponse != null) {
val jsonWithImagesAndInfo = composeJsonWithImagesAndInfo(imagesResponse)
} else {
// TODO Warning to user
Log.e(TAG, "Error: Get request returned no response")
}
... // All the rest of code
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.