[英]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.