Flow的集合功能是Kotlin中的块函数吗?

发布于 2025-01-28 23:03:46 字数 2335 浏览 0 评论 0原文

我希望通过ID列表删除记录和带有房间的相对文件。

我发现可以删除这些文件,并且在运行代码A运行代码A时无法删除记录。

我发现在运行代码B时可以删除记录。

似乎log.e.e(“我的”,“ fire”” )未在代码A中启动。我不知道为什么吗?

Q1:代码A有什么问题?

Q2:我使用流程时收集块函数吗?

Q3:fun getById(id:int):flow< rocoreTity?良好的设计吗?也许应该是fun getById(id:int):记录范围?

代码a

class RecordRepository @Inject constructor(
    private val mRecordDao:RecordDao
) {   
    override fun getByID(id:Int): Flow<MRecord?> =  mRecordDao.getByID(id).map {it?.let{ModelMapper.entityToModel(it) } }
 

    override suspend fun deleteRecord(idList: List<Int>) = withContext(Dispatchers.Default) {
        idList.forEach{
            getByID(it).collect {
               it?.let {
                   val filename = it.soundFileName
                   deleteFileOrFolder(filename)
               }
            }
        }
        Log.e("My","Fire")
        mRecordDao.deleteRecord(idList)
    }

}

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table where id=:id")
    fun getByID(id:Int): Flow<RecordEntity?> 

    @Query("delete from record_table where id in (:idList)")
    suspend fun deleteRecord(idList: List<Int>)
}

代码b

class RecordRepository @Inject constructor(
    private val mRecordDao:RecordDao
) {   
    override fun getByID(id:Int): Flow<MRecord?> =  mRecordDao.getByID(id).map {it?.let{ModelMapper.entityToModel(it) } }


    override suspend fun deleteRecord(idList: List<Int>) = withContext(Dispatchers.Default) { 
        mRecordDao.deleteRecord(idList)
    }

}

//The same

添加了内容:

arpit shukla:谢谢!

我发现许多查询样品可以使用代码C返回使用房间的流量数据。

我认为代码D足够了,很简单,

我很困惑为什么我需要在房间中使用流,您知道我只希望实体一次,您能告诉您我?

代码C

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table ORDER BY createdDate desc")
    fun listRecord():  Flow<List<RecordEntity>>
}

代码D

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table ORDER BY createdDate desc")
    suspend  fun listRecord(): List<RecordEntity>
}

I hope to delete records by Id list and relative files with Room.

I find the files can be deleted and the records can't be deleted when I run Code A

I find the records can be deleted when I run Code B.

It seems that Log.e("My","Fire") is not launched in Code A. I don't know why?

Q1: What's wrong with Code A ?

Q2: Is the collect a block function when I use Flow?

Q3: Is fun getByID(id:Int): Flow<RecordEntity?> good design? maybe it should be fun getByID(id:Int): RecordEntity? .

Code A

class RecordRepository @Inject constructor(
    private val mRecordDao:RecordDao
) {   
    override fun getByID(id:Int): Flow<MRecord?> =  mRecordDao.getByID(id).map {it?.let{ModelMapper.entityToModel(it) } }
 

    override suspend fun deleteRecord(idList: List<Int>) = withContext(Dispatchers.Default) {
        idList.forEach{
            getByID(it).collect {
               it?.let {
                   val filename = it.soundFileName
                   deleteFileOrFolder(filename)
               }
            }
        }
        Log.e("My","Fire")
        mRecordDao.deleteRecord(idList)
    }

}

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table where id=:id")
    fun getByID(id:Int): Flow<RecordEntity?> 

    @Query("delete from record_table where id in (:idList)")
    suspend fun deleteRecord(idList: List<Int>)
}

Code B

class RecordRepository @Inject constructor(
    private val mRecordDao:RecordDao
) {   
    override fun getByID(id:Int): Flow<MRecord?> =  mRecordDao.getByID(id).map {it?.let{ModelMapper.entityToModel(it) } }


    override suspend fun deleteRecord(idList: List<Int>) = withContext(Dispatchers.Default) { 
        mRecordDao.deleteRecord(idList)
    }

}

//The same

Added Content:

To Arpit Shukla: Thanks!

I find many query samples to return Flow data with Room using Code C.

I think Code D is enought and it's simple

I'm confused why I need to use Flow in Room, you know I only want the entities once mostly, could you tell me?

Code C

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table ORDER BY createdDate desc")
    fun listRecord():  Flow<List<RecordEntity>>
}

Code D

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table ORDER BY createdDate desc")
    suspend  fun listRecord(): List<RecordEntity>
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

林空鹿饮溪 2025-02-04 23:03:46

收集函数永远悬挂。它永远不会恢复。因此,您在收集之后放置的任何代码将永远不会执行。 的问题。

这是代码A

override suspend fun deleteRecord(idList: List<Int>) = withContext(Dispatchers.Default) {
    idList.forEach {
       launch {
           getByID(it).collect {
               it?.soundFileName?.let { deleteFileOrFolder(it) }
           }
       }
    }
    Log.e("My","Fire")
    mRecordDao.deleteRecord(idList)
}

另外,您无需在代码中切换调度器,房间会自动这样做。

编辑:如果您需要仅获取记录范围的列表一次,则代码D是更好的方法。当我们需要观察查询结果中的更改时,需要流量。例如,在UI中显示RecordEntity的列表时,如果数据库中的数据更改,则我们希望更新UI,为此,我们可以从DAO返回flow

对于您的特定情况,您可以这样做:

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table where id=:id")
    suspend fun getByID(id:Int): RecordEntity?
}

override suspend fun deleteRecord(idList: List<Int>) {
    idList.forEach { id ->
        getByID(id)?.soundFileName?.let { deleteFileOrFolder(it) }
    }
    Log.e("My","Fire")
    mRecordDao.deleteRecord(idList)
}

collect function suspends forever. It never resumes. So any code you put after collect will never be executed. This is the problem with Code A.

If you want to make code A work, you should collect each flow in a separate coroutine using the launch function.

override suspend fun deleteRecord(idList: List<Int>) = withContext(Dispatchers.Default) {
    idList.forEach {
       launch {
           getByID(it).collect {
               it?.soundFileName?.let { deleteFileOrFolder(it) }
           }
       }
    }
    Log.e("My","Fire")
    mRecordDao.deleteRecord(idList)
}

Also, you need not switch Dispatchers in the code, Room does that automatically.

Edit: If you need to get the list of RecordEntity only once, code D is a better approach. Flow is required when we need to observe the changes in the query result. For example, while displaying a list of RecordEntity in the UI, we would want to update the UI if the data in database changes and for that we can return Flow from Dao.

For your particular case, you can do this:

@Dao
interface  RecordDao {
    @Query("SELECT * FROM record_table where id=:id")
    suspend fun getByID(id:Int): RecordEntity?
}

override suspend fun deleteRecord(idList: List<Int>) {
    idList.forEach { id ->
        getByID(id)?.soundFileName?.let { deleteFileOrFolder(it) }
    }
    Log.e("My","Fire")
    mRecordDao.deleteRecord(idList)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文