kotlin 链流程取决于结果状态

P. *_*rov 6 kotlin kotlin-coroutines kotlin-flow

我正在寻找最“干净”的方式来实现以下逻辑:

  • 我有N个方法,每个人都返回Flow<Result<SOME_TYPE>>(类型不同)
  • 我想链接这些方法,因此如果 1 返回 Result.Success,则调用 2nd,依此类推。

最明显的方法是:

methodA().map { methodAResult ->
  when (methodAResult) {
    is Result.Success -> {
      methodB(methodAResult).map { methodBResult ->
        when (methodBResult) {
          is Result.Success -> {
            methodC(methodAResult).map { methodCResult ->
              when (methodCResult) {
                is Result.Success -> TODO()
                is Result.Failure -> TODO()
              }
            }
          }
          is Result.Failure -> TODO()
        }
      }
     }
     is Result.Failure -> TODO()
   }
 }
Run Code Online (Sandbox Code Playgroud)

但它看起来就像是一个众所周知的“回调地狱”。你有什么想法如何避免它吗?

Мих*_*аль 6

我相信这可以用变换运算符来压平:

methodA().transform { methodAResult ->
    when (methodAResult) {
        is Success -> methodB(methodAResult).collect { emit(it) }
        is Failure -> TODO()
    }
}.transform { methodBResult ->
    when (methodBResult) {
        is Success -> methodC(methodBResult).collect { emit(it) }
        is Failure -> TODO()
    }
}.transform { methodCResult ->
    when (methodCResult) {
        is Success -> TODO()
        is Failure -> TODO()
    }
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*sel 5

对 \xd0\x9c\xd0\xb8\xd1\x85\xd0\xb0\xd0\xb8\xd0\xbb \xd0\x9d\xd0\xb0\xd1\x84\xd1\x82\xd0 提供的解决方案稍作修改\xb0\xd0\xbb\xd1\x8c

\n
    methodA()\n        .flatMapMerge {\n            when (it) {\n                is Result.Success -> methodB(it)\n                is Result.Failure -> emptyFlow()\n            }\n        }.flatMapMerge {\n            when (it) {\n                is Result.Success -> methodC(it)\n                is Result.Failure -> emptyFlow()\n            }\n        }.collect {\n            when (it) {\n                is Result.Success -> TODO()\n                is Result.Failure -> TODO()\n            }\n        }\n\n
Run Code Online (Sandbox Code Playgroud)\n

将一个流的输出合并到另一个流是 flatMap 的目标,因此使用 flatMap 看起来更干净一些。

\n

如果此 Result 类具有mapfoldgetOrNulltype 方法,则可以进一步清理该方法,并且可以删除 when 块。

\n

此外,如果您需要将失败传播到收集,那么您可以将对emptyFlow 的调用替换为仅输出您想要的失败的流。

\n