将一系列 ZIO 的所有成功和失败集中在一起?
Collect all of the successes and failures of a sequence of ZIOs together?
我有一堆IO
,所有这些都可能成功或失败:
val result: Seq[IO[MyFailure, MySuccess]] = ...
我需要总结结果,以便我可以检查所有失败和所有成功一起:
case class MySummary(failures: Seq[MyFailure], successes: Seq[MySuccess])
def makeSummary(results: Seq[IO[MyFailure, MySuccess]]): UIO[MySummary] = ???
起初这似乎与 foreach
非常相似,但仔细检查后我发现这对这里没有帮助。对于 Future
我通常使用 sequence
,对于 Seq[Either[A,B]]
我可以使用 partitionMap
。 ZIO 中的等效方法是什么?
我对 ZIO 不熟悉,可能有一种内置的方法可以实现相同的目的。
我会选择以下内容:
def makeSummary(results: Seq[IO[MyFailure, MySuccess]]): UIO[MySummary] = {
results.foldLeft(ZIO.succeed(MySummary(Seq(), Seq()))) { (acc, io) =>
acc.flatMap { summary =>
io.fold(
err => summary.copy(failures = summary.failures :+ err),
suc => summary.copy(successes = summary.succcesses :+ suc)
)
}
}
}
您无法使用 Future.sequence
检查所有失败,如果有的话,您只会返回第一个失败。
Future.sequence
的 ZIO 等价物是 ZIO.collectAll
,这几乎等同于 ZIO.foreach(result)(identity)
。
如果你真的需要累积所有错误,那么你应该使用 ZIO.validate
并且对于分区还有 ZIO.partition
.
一些比较代码:
val result: Seq[IO[MyFailure, MySuccess]] = ???
val withCollectAll: IO[MyFailure, Seq[MySuccess]] = ZIO.collectAll(result)
val withForeach: IO[MyFailure, Seq[MySuccess]] = ZIO.foreach(result)(identity)
val withValidate: IO[::[MyFailure], Seq[MySuccess]] = ZIO.validate(result)(identity) //`::` just means that the list cannot be empty
val withPartition: UIO[(Iterable[MyFailure], Iterable[MySuccess])] = ZIO.partition(result)(identity)
makeSummary
的代码 ZIO.partition
:
def makeSummary(results: Seq[IO[MyFailure, MySuccess]]): UIO[MySummary] =
ZIO.partition(results)(identity).map { case (f, s) => MySummary(f.toSeq, s.toSeq) }
我有一堆IO
,所有这些都可能成功或失败:
val result: Seq[IO[MyFailure, MySuccess]] = ...
我需要总结结果,以便我可以检查所有失败和所有成功一起:
case class MySummary(failures: Seq[MyFailure], successes: Seq[MySuccess])
def makeSummary(results: Seq[IO[MyFailure, MySuccess]]): UIO[MySummary] = ???
起初这似乎与 foreach
非常相似,但仔细检查后我发现这对这里没有帮助。对于 Future
我通常使用 sequence
,对于 Seq[Either[A,B]]
我可以使用 partitionMap
。 ZIO 中的等效方法是什么?
我对 ZIO 不熟悉,可能有一种内置的方法可以实现相同的目的。
我会选择以下内容:
def makeSummary(results: Seq[IO[MyFailure, MySuccess]]): UIO[MySummary] = {
results.foldLeft(ZIO.succeed(MySummary(Seq(), Seq()))) { (acc, io) =>
acc.flatMap { summary =>
io.fold(
err => summary.copy(failures = summary.failures :+ err),
suc => summary.copy(successes = summary.succcesses :+ suc)
)
}
}
}
您无法使用 Future.sequence
检查所有失败,如果有的话,您只会返回第一个失败。
Future.sequence
的 ZIO 等价物是 ZIO.collectAll
,这几乎等同于 ZIO.foreach(result)(identity)
。
如果你真的需要累积所有错误,那么你应该使用 ZIO.validate
并且对于分区还有 ZIO.partition
.
一些比较代码:
val result: Seq[IO[MyFailure, MySuccess]] = ???
val withCollectAll: IO[MyFailure, Seq[MySuccess]] = ZIO.collectAll(result)
val withForeach: IO[MyFailure, Seq[MySuccess]] = ZIO.foreach(result)(identity)
val withValidate: IO[::[MyFailure], Seq[MySuccess]] = ZIO.validate(result)(identity) //`::` just means that the list cannot be empty
val withPartition: UIO[(Iterable[MyFailure], Iterable[MySuccess])] = ZIO.partition(result)(identity)
makeSummary
的代码 ZIO.partition
:
def makeSummary(results: Seq[IO[MyFailure, MySuccess]]): UIO[MySummary] =
ZIO.partition(results)(identity).map { case (f, s) => MySummary(f.toSeq, s.toSeq) }