Kotlin 流程似乎没有从 Composable 中收集

Kotlin flow doesn't appear to be collecting from Composable

提问人:Alexander Trauzzi 提问时间:11/5/2023 更新时间:11/5/2023 访问量:38

问:

我创建了一个类来包装 Kotlin GraphQL 查询:

class GraphQuery<DataType : Query.Data>(
    private val api: Api,
    private val queryFactory: suspend () -> Query<DataType>,
) {

    private val control: MutableStateFlow<GraphQueryState<DataType>> = MutableStateFlow(GraphQueryState.NotStarted())

    public val flow = control
        .onStart { emit(GraphQueryState.Loading()) }
        .flatMapConcat {

            api.client
                .query(queryFactory())
                .fetchPolicy(FetchPolicy.NetworkOnly)
                .watch()
                .map { response ->
                    when (response.hasErrors()) {
                        true -> GraphQueryState.Error(response.errors!!)
                        else -> GraphQueryState.Ready(response.data!!)
                    }
                }
        }

    public fun update(data: DataType) {
        control.value = GraphQueryState.Updating(data)
    }

    public fun refresh() {
        control.value = GraphQueryState.Loading()
    }
}

一般目的是减少样板代码,并为我的应用程序提供一致的数据检索方法。

我通过我的 :ViewModel

@HiltViewModel
class EditWebPaymentSettingsViewModel @Inject constructor (
    appSettings: DataStore<Settings>,
    api: Api,
) : ViewModel() {

    private val settingsQuery = GraphQuery(api) {

        val settings = appSettings.data.last()

        SettingsForAdminQuery(
            UUID.fromString(settings.currentOrganizationId),
            SupportedSettingPurpose.WebPayment.value,
        )
    }

    public val settings = settingsQuery.flow
}

然后在我的应用程序中使用它:Composable

@Composable
fun EditWebPaymentSettingsScreen(
    done: () -> Unit,
    viewModel: EditWebPaymentSettingsViewModel = hiltViewModel()
) {

    val webPaymentSettings by viewModel.settings.collectAsStateWithLifecycle(GraphQueryState.NotStarted())

    when (webPaymentSettings) {

        is GraphQueryState.Loading,
        is GraphQueryState.NotStarted -> Loading()

        is GraphQueryState.Ready,
        is GraphQueryState.Updating -> TODO()

        is GraphQueryState.Error -> TODO()
    }
}

我的问题是,我从来没有去过任何一个街区。My 无限期地保持初始值,我的查询永远不会运行。TODO()webPaymentSettingsNotStarted

有没有简单的方法可以判断为什么我的查询从不运行?我的实用程序类做了一个,这让我认为查询应该在第一个值之后发出。我的印象是这是一个热流,因为我正在使用 ,但也许我错过了什么?flatMapConcatMutableStateFlow

Android Kotlin android-jetpack-compose kotlin-flow apollo-kotlin

评论


答:

0赞 BoD 11/5/2023 #1

如果我们查看您的流程链,我们有:

control
        .onStart { emit(GraphQueryState.Loading()) }

这是一个首先发出 ,然后(可能不是你想要的)的流,然后LoadingNotStarted

.flatMapConcat {
  <Apollo Kotlin watch>
}

它接收排放并用 Apollo Kotlin 调用替换它们。

(注意:永远不会完成。watch()

所以你永远不应该得到 nor ,而只能得到 or 。LoadingNotStartedReadyError

但你永远不会得到 - 会不会是那个块?ReadyErrorappSettings.data.last()