我想将Flow用作存储库中所有函数的返回类型。例如:

suspend fun create(item:T): Flow<Result<T>>

此函数应调用2个数据源:remote(将数据保存在服务器上)和local(将从服务器返回的数据保存在本地)。问题是如何实现这种情况:
  • 尝试使用RemoteDataSource保存数据
  • 如果1.失败-尝试N次M次超时
  • (如果数据最终已从服务器返回)-与LocalDataSource本地
  • 相同
  • 返回带有本地保存数据的流

  • 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
      }
    }
    

    这是一个可行的主意吗?

    最佳答案

    我认为您有正确的主意,但您正在尝试立即做所有事情。
    我发现最有效(且容易)的是:

  • 来自本地数据源的公开数据流(使用Room即可轻松完成)
  • 一个或多个公开的挂起函数,例如createrefresh,它们在远程数据源上运行并保存到本地一个(如果没有错误)

  • 例如,我有一个可以在我的项目中提取车辆的存储库(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/

    10-13 07:54