从未在Kotlin Flow中收集过的发射功能

问题描述

我正在尝试一个函数来执行所有API调用和Room存储。但是在此功能中,我有一个emit不起作用。

fun getAPI() = flow {
    emit(State.Loading())
    // suspend function
    val response = safeApiCall{
        // retrofit request here
    }

    when (response) {
        is Success -> {
            // Emit here not working
            response.data?.let { emit(State.InsertOK(it)) }
            // Insert data in Room
            response.data?.let { insertQuery(it) }
        }
        is Error -> {
            emit(State.Error(response.error)
        }
    }
    
    emitAll(getQuery().map { State.Success(it) })
}

这些值收集在我的viewmodel中

private val _result = mutablelivedata<State<APIResult>>()
val result: LiveData<State<APIResult>>
        get() = _result 

fun getAPI( ) = viewmodelScope.launch {
        repository.getAPI()
            .collect {
                _result .postValue(it)
            }
    }

我尝试在emit之后和之前进行DAO调用,但没有任何变化。 我在Flow上做错了什么事,而这种意图不该这样使用?

解决方法

您应该打一些terminal operator,例如collect()

myFlow().collect { value ->
    println("Received $value")
}
,

流发射仅在启动的上下文中有效,因此不确定是否在某个地方启动了另一个上下文或其他东西。

但是这里有一些解决方法。您可以返回MutableStateFlow,并且可以像收集常规流一样进行收集,而无需进行任何更改,但必须在函数定义中返回MutableStateFlow。像下面这样。用ResponseModel替换api您的响应。 MutableStateFlow就像实时数据一样,但是具有流的好处,因此您不必做太多更改。

fun myFlow() = MutableStateFlow<State<ResponseModel>> {
    val mutableFlow = MutableStateFlow<State<ResponseModel>>(State.Loading())

    val response = safeApiCall{
        // retrofit request here
    }

    when (response) {
        is Success -> {
            // Emit here not working
            response.data?.let { mutableFlow.value = State.InsertOK(it) }
            // Insert data in Room
            response.data?.let { insertQuery(it) }
        }
        is Error -> {
            mutableFlow.value = State.Error(response.error)
        }
    }
    
   // emitAll(getQuery().map { State.Success(it) }) //here also assign value accordingly
   return mutableFlow
}