【问题标题】:How to chain Coroutine Flow?如何链接协程流?
【发布时间】:2020-03-02 09:16:56
【问题描述】:

我可以通过以下方式轻松链接coroutineFlows:

val someFlow = flow { //Some logic that my succeed or throw error }
val anotherFlow = flow { // Another logic that my succeed or throe error }

val resultingFlow = someFlow.flatmapLatest(anotherFlow)

但是如果我想单独重试someFlowanotherFlow 如果someFlow 已经成功返回一个值但anotherFlow 失败,我想通过使用来自的值重试anotherFlow someFlow(成功时返回的值)。

最好的方法是什么?

【问题讨论】:

    标签: kotlin-coroutines kotlin-flow


    【解决方案1】:

    您可以像这样在anotherFlow 上使用retryWhen 运算符:

    val someFlow = flow { 
        //Some logic that my succeed or throw error 
    }
    
    val anotherFlow = flow { 
        // Another logic that my succeed or throe error 
    }
    .retryWhen { cause, attempt ->
        if (cause is IOException) {    // retry on IOException
            emit(“Some value”)         // emit anything you want before retry
            delay(1000)                // delay for one second before retry
            true
        } else {                       // do not retry otherwise
            false
        }
    }
    
    val resultingFlow = someFlow.flatmapLatest(anotherFlow)
    

    请小心,因为您最终可能会永远重试。使用attempt 参数检查您重试的次数。

    这里是retryWhen运营商官方文档:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/retry-when.html

    【讨论】:

    • 这会自动重试请求,但如果我只想在(例如)单击按钮时重试呢?
    • 确保流程运行所在的作业已完成,并使用流程启动另一个作业/协程。
    • @ArchieG.Quiñones 对于您的用例,您可以使用 suspendCancellableCoroutine 并通过回调单击按钮恢复继续
    【解决方案2】:

    您是否考虑过使用zip
    我没有测试过或其他任何东西,但这可能值得一试。

    val someFlow = flow {}
    val anotherFlow = flow {}
    someFlow.zip(anotherFlow) { some, another ->
        if(another is Resource.Error)
            repository.fetchAnother(some)
        else
            some
    }.collect {
        Log.d(TAG, it)
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2020-04-28
      • 2022-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      相关资源
      最近更新 更多