Scala 同时为fs2.Stream的所有元素安排计算

Scala 同时为fs2.Stream的所有元素安排计算,scala,functional-programming,scala-cats,fs2,Scala,Functional Programming,Scala Cats,Fs2,我有一个fs2.Stream由一些元素组成(可能是无限的),我想为流中的所有元素同时安排一些计算。这是我试过的 implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) implicit val timer: Timer[IO] = IO.timer(ExecutionContext.global) val stream = for { id <- fs2.Stream.emits

我有一个
fs2.Stream
由一些元素组成(可能是无限的),我想为流中的所有元素同时安排一些计算。这是我试过的

implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
implicit val timer: Timer[IO]     = IO.timer(ExecutionContext.global)

val stream = for {
  id <- fs2.Stream.emits(List(1, 2)).covary[IO]
  _ <- fs2.Stream.awakeEvery[IO](1.second)
  _ <- fs2.Stream.eval(IO(println(id)))
} yield ()

stream.compile.drain.unsafeRunSync()

这不是我们所期望的。我想为原始流的所有元素交错安排计划计算,但不要等到第一个流终止(由于无限计划,这永远不会发生)。

根据@KrzysztofAtłasik和@LuisMiguelMejíaSuárez给出的提示,我刚刚提出了一个解决方案:

val originalStream = fs2.Stream.emits(List(1, 2))

val scheduledComputation = originalStream.covary[IO].map({ id =>
        fs2.Stream.awakeEvery[IO](1.second).evalMap(_ => IO.delay(println(id)))
}).fold(fs2.Stream.empty.covaryAll[IO, Unit])((result, stream) => result.merge(stream)).flatten
@KrzysztofAtłasik在评论中提出的解决方案是交错的
id您的意思是希望第一个流的元素以1秒间隔的顺序出现吗?还是希望1和2同时出现,然后以1秒的间隔重复?
flatMap
是顺序的,但需要并行处理。您可以使用
zip
@KrzysztofAtłasik来实现这一点。我希望计算每1秒并行运行一次原始流的所有元素。如果您提供预期结果,则会更容易,因为很难理解您想要实现什么。您可以切换
id吗?例如,您可以切换
fs2.Stream.emits(List(1,2)).covary[IO].delayBy(1.second)。重复
。但正如我所说,很难说你的意图是什么。我认为编辑您的问题并提供更好的预期结果会使您受益匪浅。
val originalStream = fs2.Stream.emits(List(1, 2))

val scheduledComputation = originalStream.covary[IO].map({ id =>
        fs2.Stream.awakeEvery[IO](1.second).evalMap(_ => IO.delay(println(id)))
}).fold(fs2.Stream.empty.covaryAll[IO, Unit])((result, stream) => result.merge(stream)).flatten
val scheduleEachElementIndividually = originalStream.covary[IO].map({ id =>
                                 //id.seconds
        fs2.Stream.awakeEvery[IO](id.second).evalMap(_ => IO.delay(println(id)))
}).fold(fs2.Stream.empty.covaryAll[IO, Unit])((result, stream) => result.merge(stream)).flatten
val str = for {
  id <- Stream.emits(List(1, 5, 7)).covary[IO]
  res = timer.sleep(id.second) >> IO(println(id))
} yield res

val stream =  str.parEvalMapUnordered(5)(identity)

stream.compile.drain.unsafeRunSync()
 val stream = Stream.emits(List(1, 5, 7))
   .map { id => 
     Stream.eval(timer.sleep(id.second) >> IO(println(id))) }
   .parJoinUnbounded

stream.compile.drain.unsafeRunSync()