下面是代码:userDao.getUsers
从Room数据库返回Flow<List<User>>
。userService.getUsers
从远程服务器返回Flow<List<User>>
。
class MainViewModel(
private val userService: UserService,
private val userDao: UserDao
) : ViewModel() {
var resultState by mutableStateOf<List<UserEntity>>(emptyList())
private set
init {
viewModelScope.launch {
flow {
emit(userService.getUsers())
}.onEach { userList ->
val userEntities =
userList.map { user ->
UserEntity(
user.id,
user.name, user.username, user.email
)
}
userDao.insertUsers(userEntities)
}.flatMapConcat {
userDao.getUsers()
} .catch { emitAll(userDao.getUsers()) }
.flowOn(Dispatchers.IO)
.collect { list ->
resultState = list
}
}
}
}
下面我修改了代码,删除了flatMapConcat
。为什么?你可能会问。我认为它没有concatinate任何东西,所以我删除了它。现在我有这个代码:
class MainViewModel(
private val userService: UserService,
private val userDao: UserDao
) : ViewModel() {
var resultState by mutableStateOf<List<UserEntity>>(emptyList())
private set
init {
viewModelScope.launch {
flow {
emit(userService.getUsers())
}.onEach { userList ->
val userEntities =
userList.map { user ->
UserEntity(
user.id,
user.name, user.username, user.email
)
}
userDao.insertUsers(userEntities)
}
// flatMapConcat is removed
userDao.getUsers()
.catch { emitAll(userDao.getUsers()) }
.flowOn(Dispatchers.IO)
.collect { list ->
resultState = list
}
}
}
}
但是,现在resultState不再更新,flow
已经用用户填充了数据库,现在我调用userDao.getUsers
,这将返回一个Flow
。我调用collect
来检索一些数据,但总是失败。问题可能是userDao.getUsers
在flow
之前完成,但这些只是普通函数,因此它们必须顺序执行。当我调用userDao.getUsers
时,数据库必须填充一些数据。这是事件发生的顺序。请解释一下为什么修改后的代码不起作用。谢谢阅读。
1条答案
按热度按时间dldeef671#
Kotlin流(通常)为cold。
在修改后的代码中,
这只不过是定义了一个冷流。那段代码根本就没有运行。
.flatMapConcat
的旧代码将该流与.collect
链接在一起,从而使该流运行。你说的对,你的代码没有任何东西可以连接,
.flatMapConcat
之前的流只有一个元素。因此你可以简单地写
这段代码和你以前的代码有点不同。重试机制不会捕捉
userService.getUsers()
的异常,我会让你决定这是否重要。顺便说一句,我相信你不需要
.flowOn(Dispatchers.IO)
,因为Flow
-返回房间的方法已经是主要的安全。