我们如何可以从另一个收集或嵌套的流中收集流?

huangapple go评论61阅读模式
英文:

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&lt;List&lt;DatedTask&gt;&gt; which you can use elsewhere as needed.

Maybe you can do this using combine.

val datedTasksFlow: Flow&lt;List&lt;DatedTasks&gt;&gt; = allRecords.flatMapLatest { records -&gt;
    val flowsList = records.map { record -&gt;
        taskRepository.getDatedTasks(record.createOn)
            .map { DatedTasks(record, it) }
    }
    combine(flowsList).map { it.toList } // convert the arrays to lists
}

</details>



huangapple
  • 本文由 发表于 2023年2月27日 18:49:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75579489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定