我想将Flow用作存储库中所有函数的返回类型。例如:
suspend fun create(item:T): Flow<Result<T>>
此函数应调用2个数据源:remote(将数据保存在服务器上)和local(将从服务器返回的数据保存在本地)。问题是如何实现这种情况:
RemoteDataSource和LocalDataSource都具有有趣的带有相同签名的
create
:suspend fun create(item:T): Flow<Result<T>>
因此它们都返回数据流。如果您对如何实施有任何想法,我将不胜感激。
------更新#1 ------
可能的解决方案的一部分:
suspend fun create(item:T): Flow<T> {
// save item remotely
return remoteDataSource.create(item)
// todo: call retry if fails
// save to local a merge two flows in one
.flatMapConcat { remoteData ->
localDataSource.create(remoteData)
}
.map {
// other mapping
}
}
这是一个可行的主意吗?
最佳答案
我认为您有正确的主意,但您正在尝试立即做所有事情。
我发现最有效(且容易)的是:
create
或refresh
,它们在远程数据源上运行并保存到本地一个(如果没有错误)例如,我有一个可以在我的项目中提取车辆的存储库(
isCurrent
信息仅是本地的,而isLeft
/ isRight
的信息是因为我使用了Either
,但所有错误处理均适用):class VehicleRepositoryImpl(
private val localDataSource: LocalVehiclesDataSource,
private val remoteDataSource: RemoteVehiclesDataSource
) : VehicleRepository {
override val vehiclesFlow = localDataSource.vehicleListFlow
override val currentVehicleFlow = localDataSource.currentVehicleFLow
override suspend fun refresh() {
remoteDataSource.getVehicles()
.fold(
ifLeft = { /* handle errors, retry, ... */ },
ifRight = { reset(it) }
)
}
private suspend fun reset(vehicles: List<VehicleEntity>) {
val current = currentVehicleFlow.first()
localDataSource.reset(vehicles)
if (current != null) localDataSource.setCurrentVehicle(current)
}
override suspend fun setCurrentVehicle(vehicle: VehicleEntity) =
localDataSource.setCurrentVehicle(vehicle)
override suspend fun clear() = localDataSource.clear()
}
希望这会有所帮助,并且您可以适应您的情况:)关于kotlin - 库模式中的Kotlin Flow,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62302693/