gpt4 book ai didi

android - 暂停协程功能,直到收到结果,然后继续

转载 作者:行者123 更新时间:2023-12-02 13:07:44 26 4
gpt4 key购买 nike

我正在慢慢学习kotlin-coroutines,希望我想从一个简单的情况开始,即我遍历列表,每次调用API调用,等待响应,进行处理,然后在每次迭代中重复该过程。

viewModelScope.launch {
list.forEach { item ->
Log.d("TESTING", "forEach iteration before calling test(): ${item.id}")

test()

Log.d("TESTING", "forEach iteration after calling test(): ${item.id}")
}
}

suspend fun test(item.id: String) = coroutineScope {
Log.d("TESTING", "suspend test before receiving response: ${item.id}")

val apiRepsonse = async {
repository.doingApiCall() {
Log.d("TESTING", "response: ${item.id}")
}
}.await()

Log.d("TESTING", "suspend test after receiving response: ${item.id}")
}

因此,如果我们想象, list包含: { 10, 15, 25, 35 }(id)

我想以 logcat接收以下内容:
Log.d("TESTING", "forEach iteration before calling test(): 10")
Log.d("TESTING", "suspend test before receiving response: 10")
Log.d("TESTING", "response: 10")
Log.d("TESTING", "suspend test after receiving response: 10")
Log.d("TESTING", "forEach iteration after calling test(): 10")
___________________
Log.d("TESTING", "forEach iteration before calling test(): 15")
Log.d("TESTING", "suspend test before receiving response: 15")
Log.d("TESTING", "response: 15")
Log.d("TESTING", "suspend test after receiving response: 15")
Log.d("TESTING", "forEach iteration after calling test(): 15")
...

但是,现在我得到这样的东西:
Log.d("TESTING", "forEach iteration before calling test(): 10")
Log.d("TESTING", "suspend test before receiving response: 10")
Log.d("TESTING", "suspend test after receiving response: 10")
Log.d("TESTING", "forEach iteration after calling test(): 10")
Log.d("TESTING", "forEach iteration before calling test(): 15")
Log.d("TESTING", "suspend test before receiving response: 15")
Log.d("TESTING", "suspend test after receiving response: 15")
Log.d("TESTING", "forEach iteration after calling test(): 15")

Log.d("TESTING", "response: 10")
Log.d("TESTING", "response: 15")

...

基本上,for-each循环移动并且不等待API异步响应。我以为 .await()是用于此场景的,但我可能在这里遗漏了一些东西,因为它显然不像我想象的那样起作用。

最佳答案

更改

val apiRepsonse = async {
repository.doingApiCall() {
Log.d("TESTING", "response: ${item.id}")
}
}.await()


val apiRepsonse = async {
Log.d("TESTING", "Start work in another 'thread'.")
repository.doingApiCall() {
Log.d("TESTING", "Finish work in another 'thread'.")
}
}.await()
Log.d("TESTING", "response: ${apiRepsonse.id}")

这样一来,您等待交付的值(value)就得到了实际使用。

我认为这将消除您的LogCat困惑。

我本人试图解决您的问题,我已将其编写为可以理解的测试:
class TestFoo {

@Test
fun foo() {
val job = GlobalScope.launch {
listOf("10", "15").forEach { item ->
println("TESTING forEach iteration before calling test(): ${item}")

test(item)

println("TESTING forEach iteration after calling test(): ${item}")
}
}
while(job.isActive) {
// wait
}
}

private suspend fun test(item: String) = coroutineScope {
println("TESTING suspend test before receiving response: ${item}")

val apiRepsonse = async {
delay(1000)
println("TESTING response: ${item}")
"Hello"
}.await()

println("TESTING suspend test after receiving response: ${item}")
}

}

这是“LogCat”:

enter image description here

您是否因为 repository.doingApiCall()内部发生了一些线程而获得了不同的日志?

关于android - 暂停协程功能,直到收到结果,然后继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60376171/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com