You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在点击事件触发时使用Kotlin Flow的retry函数实现API重试?

问题解答

Flow的retry机制能否满足该场景?

不能。Flow自带的retry()、retry(n)这类方法是自动触发重试,会在API失败后立刻(或按配置策略)重复调用,完全不需要用户手动交互。而你的场景需要等待用户主动点击重试按钮才重新发起请求,这种手动触发的逻辑,默认retry机制无法适配。

最佳实现方案

核心思路是用一个触发型Flow接收用户的重试点击事件,再将这个事件流与API请求流绑定,每次收到重试事件就重新发起API调用。具体实现如下:

1. Repository层(无需修改)

保持原有代码,它只负责提供基础API请求Flow:

fun getData(): Flow<Result<T>> = service.getData()

2. ViewModel层

新增MutableSharedFlow接收重试事件,通过flatMapLatest将事件流与API请求流结合:

class YourViewModel(private val repo: YourRepository) : ViewModel() {
    // 重试触发事件流,SharedFlow适合一次性事件场景
    private val retryTrigger = MutableSharedFlow<Unit>(extraBufferCapacity = 1)

    // 组合数据流:初始请求 + 重试事件触发新请求
    val data: Flow<Result<T>> = flow {
        emitAll(repo.getData()) // 首次进入先发起请求
    }.flatMapLatest { initialResult ->
        if (initialResult is Result.Error) {
            // 请求失败时,监听重试事件,每次触发就重新请求
            retryTrigger.flatMapLatest {
                repo.getData()
            }.onStart { emit(initialResult) } // 先保留错误状态,直到新请求返回
        } else {
            // 请求成功后,仅返回成功结果,不再监听重试
            flowOf(initialResult)
        }
    }

    // 供Fragment调用的重试方法
    fun retry() {
        viewModelScope.launch {
            retryTrigger.emit(Unit)
        }
    }
}

3. Fragment层

修改点击事件,调用ViewModel的retry()方法即可:

viewLifecycleOwner.lifecycleScope.launch {
    viewModel.data.collect { result ->
        when(result) {
            is Result.Success -> {
                hideRetryButton()
                // 填充列表逻辑
            }
            is Result.Error -> {
                showRetryButton()
                // 显示错误提示
            }
        }
    }
}

retryButton.setOnClickListener {
    viewModel.retry()
}

补充说明

  • 选用MutableSharedFlow是因为重试事件是一次性的,无需保存状态,extraBufferCapacity = 1可避免Flow未收集时发送事件丢失。
  • flatMapLatest会在收到新重试事件时,取消可能还在进行的旧请求,确保只处理最新的一次请求,符合大多数场景需求。

内容的提问来源于stack exchange,提问作者Amr Jyniat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:35:24