[英]Unable to Execute code after Kotlin Flow collect
I'm trying to execute some code after calling collect
on a Flow<MyClass>
.我正在尝试在
Flow<MyClass>
上调用collect
后执行一些代码。 I'm still kind of new to using Flows so I don't understand why the code after the function doesn't get called.我对使用 Flows 还是有点陌生,所以我不明白为什么函数后面的代码没有被调用。
How I use the Flow:我如何使用流程:
incidentListener = FirebaseUtils.databaseReference
.child(AppConstants.FIREBASE_PATH_AS)
.child(id)
.listen<MyClass>() //This returns a Flow<MyClass?>?
How I consume the Flow:我如何消耗流量:
private suspend fun myFun() {
viewmodel.getListener()?.collect { myClass->
//do something here
}
withContext(Dispatchers.Main) { updateUI() } //the code never reaches this part
}
How myFun()
is called:如何
myFun()
:
CoroutineScope(Dispatchers.IO).launch {
myFun()
}
As far as what I've tried to make it work I've tried closing the coroutine context and it didn't work.至于我试图让它工作的东西,我已经尝试关闭协程上下文,但它没有用。 I'm assuming Flows work differently than regular coroutines.
我假设 Flows 的工作方式与常规协程不同。
Update:更新:
I'm listening through Firebase using this block of code.我正在使用此代码块通过 Firebase 进行侦听。 I don't know if it'll help but maybe the way I implemented it is causing the issue?
我不知道它是否会有所帮助,但也许我实施它的方式导致了问题?
inline fun <reified T> Query.listen(): Flow<T?>? =
callbackFlow {
val valueListener = object : ValueEventListener {
override fun onCancelled(databaseError: DatabaseError) {
close()
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
try {
val value = dataSnapshot.getValue(T::class.java)
offer(value)
} catch (exp: Exception) {
if (!isClosedForSend) offer(null)
}
}
}
addValueEventListener(valueListener)
awaitClose { removeEventListener(valueListener) }
}
collect
is a suspending function, the code after collect
will only run once the flow completes. collect
是一个挂起函数, collect
之后的代码只会在流程完成后运行。
Launch it in a separate coroutine:在单独的协程中启动它:
private suspend fun myFun() {
coroutineScope {
launch {
viewmodel.getListener()?.collect { myClass->
//do something here
}
}
withContext(Dispatchers.Main) { updateUI() } //the code never reaches this part
}
}
I forgot to post my own answer to this.我忘了发布我自己的答案。 I've found the problem before.
我以前发现过这个问题。 It's because I wasn't returning the
Coroutine Context
.这是因为我没有返回
Coroutine Context
。
My code has been updated since but with the code above as an example it should be written as follows:我的代码已经更新了,但以上面的代码为例,它应该写成如下:
private suspend fun myFun() {
viewmodel.getListener()?.collect { myClass->
//do something here
return@collect
}
withContext(Dispatchers.Main) { updateUI() return@withContext }
//the code should flow downwards as usual
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.