coroutines,livedata,flow

LiveData with Coroutines and Flow

我们经常在viewModel 中做些数据的操作:

1. 如果是one short 数据,我们可以这样使用:

val currentWeather: LiveData<String> = dataSource.fetchWeather()

2. 如果是flow数据,我们可以这样使用:

val currentWeatherFlow: LiveData<String> = dataSource.fetchWeatherFlow().asLiveData()

3. 如是是1+N的one short 数据:

val currentWeather: LiveData<String> = liveData {
    emit(LOADING_STRING)
    emitSource(dataSource.fetchWeather())
}

4. 如是是1+N的flow 数据:

val currentWeatherFlow: LiveData<String> = 
    dataSource.fetchWeatherFlow()
        .onStart { emit(LOADING_STRING) }
        .asLiveData()

5. one short 数据+switchMap:

val currentWeatherLiveData: LiveData<String> =
    dataSource.fetchWeather().switchMap {
         liveData { emit(heavyTransformation(it)) }
    }

6. flow 数据+map:

val currentWeatherFlow: LiveData<String> =
    dataSource.fetchWeatherFlow()
        .map { heavyTransformation(it) }
        .asLiveData()

也就是说:如果你是flow数据,那么推荐用flow api

val currentWeatherFlow: Flow<String> =
    dataSource.fetchWeatherFlow()
        .map { ... }
        .filter { ... }
        .dropWhile { ... }
        .combine { ... }
        .flowOn(Dispatchers.IO)
        .onCompletion { ... }

7. 如果有些库如Retrofit, Room已经支持suspend 函数了, 那么你可以直接调用如下:

suspend fun doOneShot(param: String) : String{
     return retrofitClient.doSomething(param)
    }


@POST("/api/....")
suspend fun doSomething(
        @Body map: @JvmSuppressWildcards Map<String, String>
    ): String
    

8. 如果一些第三方库没有支持suspend方法,只有回调的话,

可以用suspendCancellableCoroutine或是suspendCoroutine

suspend fun doOneShot(param: String) : Result<String> =
    suspendCancellableCoroutine { continuation ->
        api.addOnCompleteListener { result ->
            continuation.resume(result)
        }.addOnFailureListener { error ->
            continuation.resumeWithException(error)
        }.fetchSomething(param)
      }

9.如果你需要flow数据,采用flow 构建

 fun fetchWeatherFlow(): Flow<String> = flow {
    var counter = 0
    while(true) {
        counter++
        delay(2000)
        emit(weatherConditions[counter % weatherConditions.size])
    }
}

10. 如果要把Callback转化为flow ,采用callbackflow 构建

fun flowFrom(api: CallbackBasedApi): Flow<T> = callbackFlow {
    val callback = object : Callback {
        override fun onNextValue(value: T) {
            offer(value)
        }
        override fun onApiError(cause: Throwable) {
            close(cause)
        }
        override fun onCompleted() = close()
    }

    api.register(callback)
    awaitClose { api.unregister(callback) }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值