我遇到一个非常奇怪的问题。我在FragemtA
中有一个哈希表列表(groupList)。每次运行fragmentA
时,它应该调用checkUser
函数,并最终在其中的forEach
处显示返回值。
var id = ""
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val userId = checkUser()
activity.groupedList.forEach {
for (i in it.value) {
Log.d(TAG, "user id in groupedList" + userId)
}
}
fun checkUser(): String {
GlobalScope.launch(Dispatchers.Main) {
val response = WebApi.getOrganizationsList(activity)
if (response?.status == "success") {
id = response?.user_id.toString()
Log.d(TAG,"id in checkUser "+id)
} else {
longToast("FAIL")
}
}
return id
}
为什么我会得到这个输出?
D/xxx: user id in groupedList
D/xxx: user id in groupedList
D/xxx: id in checkUser 46
我希望id in checkUser 46
首先显示,但不会显示!
所需的输出
D/xxx: id in checkUser 46
D/xxx: user id in groupedList 46
D/xxx: user id in groupedList 46
答案 0 :(得分:2)
您正在启动线程,但不等待其完成。更改它以等待,您会没事的。顺便说一句,通常不建议使用GlobalScope。您应该考虑在您的类上实现CoroutineScope,以便可以简单地使用关键字“ launch”。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
GlobalScope.launch {
val userId = checkUser()
activity.groupedList.forEach {
for (i in it.value) {
Log.d(TAG, "user id in groupedList" + userId)
}
}
}
suspend fun checkUser(): String = suspendCoroutine { c->
GlobalScope.launch(Dispatchers.Main) {
var id = ""
val response = WebApi.getOrganizationsList(activity)
if (response?.status == "success") {
id = response?.user_id.toString()
Log.d(TAG,"id in checkUser "+id)
} else {
longToast("FAIL")
}
c.resume(id)
}
}
答案 1 :(得分:1)
首先,协程不需要返回字符串,因为您已经将其结果保存在属性id
中。
第二,您希望成为第一条消息的消息是最后一条消息,因为您要启动的协程在循环执行之后执行完毕–到forEach
循环运行时,协程还没有执行还没完成。您必须记住,由于您没有等待协程完成,因此代码不会顺序执行。
一种选择是在确定成功检索到ID值之后,在协程中执行操作(即forEach
循环):
fun checkUser() {
GlobalScope.launch(Dispatchers.Main) {
val response = WebApi.getOrganizationsList(activity)
if (response?.status == "success") {
id = response?.user_id.toString()
Log.d(TAG,"id in checkUser "+id)
activity.groupedList.forEach {
for (i in it.value) {
Log.d(TAG, "user id in groupedList" + id)
}
}
} else {
longToast("FAIL")
}
}
}