我知道我可以使用
import zio.Task
def zip3Par[A, B, C](a: Task[A], b: Task[B], c: Task[C]): Task[(A, B, C)] =
a.zipPar(b).zipWithPar(c) { case ((a, b), c) => (a, b, c) }
def zip4Par[A, B, C, D](a: Task[A], b: Task[B], c: Task[C], d: Task[D]): Task[(A, B, C, D)] =
zip3Par(a, b, c).zipWithPar(d) { case ((a, b, c), d) => (a, b, c, d) }
Run Code Online (Sandbox Code Playgroud)
并行执行 3 或 4 个任务,但如果有更优雅的解决方案,我会更受伤吗?
您可以只使用ZIO.collectAllPar任务列表:
def collectTasks(tasks: Task[Int]*):Task[List[Int]] = ZIO.collectAllPar(tasks)
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
val t1 = Task.effect{
Thread.sleep(100)
println("t1 started")
Thread.sleep(1000)
1
}
val t2 = Task.effect{
println("t2 started")
Thread.sleep(1000)
2
}
val t3 = Task.effect{
println("t3 started")
Thread.sleep(1000)
3
}
(new DefaultRuntime() {}).unsafeRun(collectTasks(t1,t2,t3))
Run Code Online (Sandbox Code Playgroud)
它将同时运行您的所有任务。
使用元组而不是列表的通用解决方案将很难在Scala 2 中实现,而没有 shapeless。它会在Scala 3 中改变,因为它们可以作为异构列表处理。
小智 5
另请注意,还有<&>组合器。这是 的别名zipPar。这将产生一个元组,如果您使用 for comprehensions,我建议您查看better-monadic-for哪些解决了 tuples in for comprehensions 的问题
这是将<&>组合器与地图一起使用的示例:
(t1 <&> t2 <&> t3 <&> t4) map {
case i1 <*> i2 <*> i3 <*> i4 => s"$i1, $i2, $i3, $i4"
}
ZIO.collectAllPar并且ZIO.collectAllParN只有在所有都ZIO具有相同的返回类型时才有效。这不是问题。