scala 如何执行两个效果并获得它们各自的返回值(可能是成功的,也可能是错误的)

vuktfyat  于 2022-11-09  发布在  Scala
关注(0)|答案(2)|浏览(147)

我尝试并行化这个顺序且失败的快速解决方案:

for
      cellTowersPayload <- CellHintTransformer.createGoogleApiPayload(cellAndWifiHints.cellHints).mapError(mapRequirementsFailure)
      googleMapsResultCellTowers <- googleMapsApi.call(cellTowersPayload)
      wifiHintsPayload <- WlanHintTransformer.createGoogleApiPayload(cellAndWifiHints.wifiHints).mapError(mapRequirementsFailure)
      googleMapsResultWifiHints <- googleMapsApi.call(wifiHintsPayload) // TODO paralleize with call cell towers
      mappedResult <- mapResult(googleMapsResultCellTowers, googleMapsResultWifiHints)
    yield mappedResult

最终的解决方案应该并行执行两个调用,并返回两个结果(每个结果可能是成功的,也可能是失败的)。因此,如果其中一个呼叫失败,不会很快失败
如何在ZIO中使用这种习惯用法?

enyaitl3

enyaitl31#

所以,这里有两件事。您可以通过在要并行化的ZIO上使用.fork并行执行操作,然后在这些分叉的纤程上执行联接。
问题是,您需要以某种方式确保这两个纤程都被执行,即使另一个纤程失败,默认情况下,如果其中一个纤程未能最大限度地减少计算,ZIO将取消另一个纤程。我们可以使用类似.either的代码来确保ZIO永远不会失败,而是返回Either[E, A]
因此,我们会这样做:

for {
  zio1 <- firstOperation().fork().either
  zio2 <- secondOperation().fork().either
  result <- zio1.zip(zio2)
  tupleResult <- result.join
} yield tupleResult
wko9yo5t

wko9yo5t2#

亚当·弗雷泽在此回答https://discord.com/channels/629491597070827530/630498701860929559/1027300896599724102

left.exit.zipPar(right.exit)

更新,请参阅Dominiks答案下的注解原因:

left.either.zipPar(right.either)

相关问题