Невозможно выполнить код после Kotlin Поток сбора - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь выполнить некоторый код после вызова collect на Flow<MyClass>. Я все еще новичок в использовании Flows, поэтому я не понимаю, почему код после функции не вызывается.

Как я использую Flow:

incidentListener = FirebaseUtils.databaseReference
                      .child(AppConstants.FIREBASE_PATH_AS)
                      .child(id)
                      .listen<MyClass>() //This returns a Flow<MyClass?>?

Как Я использую поток:

private suspend fun myFun() {
   viewmodel.getListener()?.collect { myClass->
       //do something here
   }
   withContext(Dispatchers.Main) { updateUI() } //the code never reaches this part
}

Как называется myFun():

CoroutineScope(Dispatchers.IO).launch {
   myFun()
}

Насколько я пытался заставить его работать, я пытался закрыть контекст сопрограммы и это не сработало. Я предполагаю, что потоки работают иначе, чем обычные сопрограммы.

Обновление:

Я слушаю через Firebase, используя этот блок кода. Я не знаю, поможет ли это, но, возможно, способ, которым я реализовал это, вызывает проблему?

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) }
}

1 Ответ

0 голосов
/ 19 марта 2020

collect является функцией приостановки, код после collect будет запускаться только после завершения потока.

Запустить его в отдельной сопрограмме:

private suspend fun myFun() {
   coroutineScope {
       launch {
           viewmodel.getListener()?.collect { myClass->
               //do something here
           }
       }
       withContext(Dispatchers.Main) { updateUI() } //the code never reaches this part
    }
}
...