我知道我可以使用
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) }
要并行执行3或4个任务,但是如果有一个更优雅的解决方案,我会受伤吗?
答案 0 :(得分:3)
您可以仅将ZIO.collectAllPar
与任务列表一起使用:
def collectTasks(tasks: Task[Int]*):Task[List[Int]] = ZIO.collectAllPar(tasks)
然后您可以像使用它:
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))
,它将同时运行您的所有任务。
使用元组而不是列表的通用解决方案如果没有定形,将很难在 Scala 2 中实现。它会在 Scala 3 中更改,因为这样它们就可以作为异构列表来处理。
答案 1 :(得分:3)
除了KrzysztofAtłasik的答案外,还有 collectAllParN ,其功能类似于collectAllPAr,但您可以指定要使用的最大光纤数:
val a = Task {
println("t1 started")
Thread.sleep(2000)
println("t1 finished")
1
}
val b = Task {
println("t2 started")
Thread.sleep(1000)
println("t2 finished")
2
}
val c = Task {
println("t3 started")
Thread.sleep(3000)
println("t3 finished")
3
}
val d = Task {
println("t4 started")
Thread.sleep(1000)
println("t4 finished")
4
}
您可以这样运行:
Task.collectAllParN(4)(List(a, b, c, d))
如果您有许多(数百或数千)并行任务,这特别有用,这样可以避免溢出和内存错误。继续,将要使用的光纤数量更改为2或3,然后亲自查看执行如何变化。
并行执行的另一种选择是,一旦您的消费者收到任务,就将任务放在 ZQueue 和 fork 上。
答案 2 :(得分:3)
还要注意,有class App extends React.Component {
constructor() {
super();
this.state = {
value: true,
countOfClicks: 0
};
this.pickRandom = this.pickRandom.bind(this);
}
pickRandom() {
this.setState({
value: Math.random() > 0.5, // randomly picks true or false
countOfClicks: this.state.countOfClicks + 1
});
}
// comment out the below to re-render on every click
shouldComponentUpdate(nextProps, nextState) {
return this.state.value != nextState.value;
}
render() {
return (
<div>
shouldComponentUpdate demo
<p><b>{this.state.value.toString()}</b></p>
<p>Count of clicks: <b>{this.state.countOfClicks}</b></p>
<button onClick={this.pickRandom}>
Click to randomly select: true or false
</button>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
组合器。这是<&>
的别名。这将生成一个元组,如果您用于理解,我建议您看看zipPar
,它可以解决元组问题的理解
下面是将better-monadic-for
组合器与map结合使用的示例:
<&>
(t1 <&> t2 <&> t3 <&> t4) map {
case i1 <*> i2 <*> i3 <*> i4 => s"$i1, $i2, $i3, $i4"
}
和ZIO.collectAllPar
仅在所有ZIO.collectAllParN
具有相同的返回类型时才起作用。那不是问题。