英文:
How we can collect flows from another collect or nested flow?
问题
我从Dao获取了记录的流(Flow<List<Record>
),现在基于这些记录,我需要获取另一个流的列表(Flow<List<AnotherRecord>>
),但是在另一个收集函数内部的收集函数不起作用。
allRecords.collect { records ->
withContext(Dispatchers.IO) {
records.forEach { record ->
taskRepository.getDatedTasks(record.createOn).collect {
datedTasks.add(DatedTasks(record, it))
}
}
// 这行在内部的collect之前执行,我不知道为什么?
Log.d(TAG, "getAllDatedTasks: ${datedTasks.size}")
}
}
英文:
I am getting Flow
of records (Flow<List<Record>
) from Dao, now on the basis of these records I have to fetch another list of flows (Flow<List<AnotherRecord>>
) , but collect function inside of another collect function is not working .
allRecords.collect { records ->
withContext(Dispatchers.IO) {
records.forEach { record ->
taskRepository.getDatedTasks(record.createOn).collect {
datedTasks.add(DatedTasks(record, it))
}
}
// this line executes before of inner collect , I don't know why ?
Log.d(TAG, "getAllDatedTasks: ${datedTasks.size}")
}
}
答案1
得分: 1
我没有检查我的代码是否正确,但我认为这样做更好:
allRecords.flowOn(Dispatchers.IO).flatMapConcat { record ->
taskRepository.getDatedTasks(record.createOn).collect {
datedTasks.add(DatedTasks(record, it))
}
}.collect {
Log.d(TAG, "getAllDatedTasks: ${datedTasks.size}")
}
英文:
I didn’t check if my code is right but I think it’s better like that :
allRecords.flowOn(Dispatchers.IO).flatMapConcat { record ->
taskRepository.getDatedTasks(record.createOn).collect {
datedTasks.add(DatedTasks(record, it))
}
}.collect {
Log.d(TAG, "getAllDatedTasks: ${datedTasks.size}")
}
答案2
得分: 1
A collect
call from Room is infinite, so if you collect multiple flows inside this collect block, it will never get past the first one.
You also don't need to use withContext
. Flows from Room already properly handle backgrounding their work.
You probably don't want all these collectors adding into the same mutable list, because there's no way to control it so they aren't adding multiple items. The final output should just be a Flow<List<DatedTask>>
which you can use elsewhere as needed.
Maybe you can do this using combine
.
val datedTasksFlow: Flow<List<DatedTask>> = allRecords.flatMapLatest { records ->
val flowsList = records.map { record ->
taskRepository.getDatedTasks(record.createOn)
.map { DatedTask(record, it) }
}
combine(flowsList).map { it.toList } // convert the arrays to lists
}
英文:
A collect
call from Room is infinite, so if you collect multiple flows inside this collect block, it will never get past the first one.
You also don't need to use withContext
. Flows from Room already properly handle backgrounding their work.
You probably don't want all these collectors adding into the same mutable list, because there's no way to control it so they aren't adding multiple items. The final output should just be a Flow<List<DatedTask>>
which you can use elsewhere as needed.
Maybe you can do this using combine
.
val datedTasksFlow: Flow<List<DatedTasks>> = allRecords.flatMapLatest { records ->
val flowsList = records.map { record ->
taskRepository.getDatedTasks(record.createOn)
.map { DatedTasks(record, it) }
}
combine(flowsList).map { it.toList } // convert the arrays to lists
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论