Можно ли собрать несколько потоков в один

то, что я хочу сделать, это получить сетевые данные с помощью firebase AddSnapshotListener, сохранить их в базе данных комнаты и получить данные из базы данных комнаты

так что я сделал это здесь ...

// in dataSource
fun getNetworkData(id : String) = callbackFlow<Data> {
    ....
    streamingApi.get{
        trySend(it)
    }
    ...
}


//in repository
fun insertData(id : String) = getNetworkData(id).map{
    roomDao.insert(it)
}

fun getRoomData() = roomDao.get()



// viewmodel
viewmodelScope.launch{
    repository.insertData(id).collect()
    repository.getRoomData().onEach{
        updateUi()
        ...
    }
}

а можно ли сразу так собрать?

fun insertAndGet() = flow{
    insertData().collect()
    getRoomData().collect()
}

и правильно ли собирать поток в репозиторий?

Вы хотите, чтобы база данных вашей комнаты больше не обновлялась, когда вы прекращаете показывать данные в пользовательском интерфейсе?

Arpit Shukla 27.11.2022 04:46
0
1
203
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать слияние для объединения потоков, которые принимают потоки vararg в качестве аргумента.

fun insertAndGet() = merge(insertData(),getRoomdata())

Здесь, если ваши insertData и getRoomData имеют поток одного типа,

insertAndGet() также будет в том же типе. Если они разные, оба будут объединены, но результат объединенного потока будет типа Any.

Использование:

fun someFun(){
  viewModelScope.launch{
   insertAndGet().collect{
  // You consume the emitted result by using it. And update UI based on the data.
   }
  }
}

Пожалуйста, обратитесь здесь.

Ответ принят как подходящий

insertData() немного странно, потому что возвращает поток единиц. Я думаю, что было бы более разумно использовать onEach вместо map, чтобы он, по крайней мере, возвращал поток, с которым вы теоретически могли бы что-то делать, кроме как просто передавать данные, а затем отбрасывать их.

Но в любом случае данные будут передаваться из потока getRoomData(), так что это не имеет большого значения. Если вы объедините их, вы можете просто удалить избыточные данные из потока insertData().

На мой взгляд, эти отдельные действия не стоит объединять в единый поток, потому что у них разные обязанности, но я полагаю, вы могли бы сделать следующее. Поскольку два потока выполняются бесконечно, их необходимо собирать параллельно. Этот поток просто собирает поток вставки, поэтому он выполняет свое действие, но не передает значения. Это делается в параллельной дочерней сопрограмме. Данные потока комнаты просто передаются.

fun insertAndGet() = flow {
    coroutineScope {
        async { insertData().collect() }
        emitAll(getRoomData())
    }
}

Спасибо!! Это действительно очень помогло

이응니은 27.11.2022 12:45

Другие вопросы по теме