Kotlin中Flow串联调用API异常:始终返回emptyFlow
问题分析与修复:Flow链式调用始终返回emptyFlow的问题
你的代码核心问题有两个:
- 错误使用
collect处理链式Flow:collect是Flow的终端操作,仅负责消费流中的数据,不会生成新的Flow返回。你在内部调用collect只是在协程里执行API调用逻辑,但这些逻辑的结果根本不会传递到函数的返回值里。 - 函数固定返回
emptyFlow():不管前面的API调用逻辑有没有执行,函数最后都会走到return emptyFlow(),所以最终返回的永远是空流。
修复方案
要实现依次调用三个API并返回第三个API的响应,需要用Flow的转换操作符(比如flatMapConcat)来串联各个API的Flow,让前一个API的结果作为后一个API的输入,最终返回整个链式处理后的Flow。
修复后的完整代码如下:
suspend fun getCode(): Flow<Result<ActivationCode?>> { return flow { emit(repository.settings) } .filterNotNull() .filter { settings -> !settings.urlScheme.isNullOrEmpty() && !settings.softwareStatement.isNullOrEmpty() && !settings.requestorID.isNullOrEmpty() } .flatMapConcat { settings -> // 调用第一个API并处理结果 apiFirst( settings.urlScheme!!, settings.requestorID!!, settings.softwareStatement!! ) .filter { it.isSuccess } .map { it.getOrNull() } .filterNotNull() // 调用第二个API .flatMapConcat { registrationInfo -> apiSecond( url = settings.urlScheme!!, clientId = registrationInfo.clientId, clientSecret = registrationInfo.clientSecret, grantType = registrationInfo.grantTypes[0] ) } .filter { it.isSuccess } .map { it.getOrNull() } .filterNotNull() // 调用第三个API并返回其Flow .flatMapConcat { tokenDetails -> apiThird( settings.urlScheme!!, settings.requestorID!!, "${tokenDetails.type} ${tokenDetails.token}" ) } } }
细节说明
- 用
flow { emit(repository.settings) }把settings包装成Flow,作为链式操作的起点。 filterNotNull()和filter用来校验settings的有效性,不符合条件的话流会自动终止,最终返回空流。flatMapConcat用来串联API调用:它会等待前一个Flow的结果,再用该结果生成下一个API的Flow,保证调用顺序。- 每个API调用后,用
filter { it.isSuccess }过滤成功结果,map { it.getOrNull() }和filterNotNull()处理非空响应数据,避免空指针。 - 最后一个
flatMapConcat直接返回第三个API的Flow,让整个函数的返回值就是第三个API的响应流。
内容的提问来源于stack exchange,提问作者WISHY
相关产品推荐
相关产品推荐

