Scala中具有分块响应的未来合成
我想我已经理解了未来的构图是如何工作的,但我不知道如何在第一个未来的响应块上调用下一个未来。 假设第一个future返回一个整数列表,该列表非常大。我想对一次包含2个元素的列表应用一些函数。我该怎么做 这个例子总结了我的困境:Scala中具有分块响应的未来合成,scala,Scala,我想我已经理解了未来的构图是如何工作的,但我不知道如何在第一个未来的响应块上调用下一个未来。 假设第一个future返回一个整数列表,该列表非常大。我想对一次包含2个元素的列表应用一些函数。我该怎么做 这个例子总结了我的困境: val a = Future(List(1,2,3,4,5,6)) def f(a: List[Int]) = Future(a map (_ + 2)) val res = for { list <- a chunked <- list.grouped(
val a = Future(List(1,2,3,4,5,6))
def f(a: List[Int]) = Future(a map (_ + 2))
val res = for {
list <- a
chunked <- list.grouped(2).toList
} yield f(chunked)
<console>:14: error: type mismatch;
found : List[scala.concurrent.Future[List[Int]]]
required: scala.concurrent.Future[?]
chunked <- list.grouped(2).toList
^
val a=未来(列表(1,2,3,4,5,6))
def(a:List[Int])=未来(一个映射(u2))
val res=用于{
list您不能将Future
与list
混合在一起以便于理解。所有涉及的对象必须是同一类型。此外,在您的工作示例中,您的结果值res
的类型为Future[Future[list[Int]]]
,这可能不是您想要的
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
a: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@3bd3cdc8
f: (a: List[Int])scala.concurrent.Future[List[Int]]
scala> val b: Future[List[List[Int]]] = a.map(list => list.grouped(2).toList)
b: scala.concurrent.Future[List[List[Int]]] = scala.concurrent.impl.Promise$DefaultPromise@74db196c
scala> val res: Future[List[List[Int]]] = b.flatMap(lists => Future.sequence(lists.map(f)))
res: scala.concurrent.Future[List[List[Int]]] = scala.concurrent.impl.Promise$DefaultPromise@28f9873c
用以理解
for {
b ← a.map(list ⇒ list.grouped( 2 ).toList)
res ← Future.sequence(b.map(f))
} yield res
考虑
a.map { _.grouped(2).toList }.flatMap { Future.traverse(_)(f) }
或者,如果出于某种原因,你决定只使用进行理解,下面是如何在不“作弊”的情况下:
当你说所有涉及的对象必须是同一类型时
基本上意味着a你可以删除映射
并在c下面添加一行新行,感谢这个解决方案的有效性!但是我认为,扩展这个解决方案变得非常困难。比如,如果我想进一步处理分块列表,然后应用f
这让它变得很难:(嗯,你越想“扩展”东西,它通常就变得越难……这就是程序员赚大钱的原因。)我的意思是,做更多的处理比做更少的处理更难,这并不奇怪,是吗?我编辑了答案,以展示如何做的总体思路。
a.map { _.grouped(2).toList }.flatMap { Future.traverse(_)(f) }
for {
b <- a
c <- Future.traverse(b.grouped(2).toList)(f)
} yield c
for {
b <- a
chunks = b.grouped(2).toList
processedChunks = processChunks(chunks)
c <- Future.traverse(processedChunks)
} yield c
a
.map { _.grouped(2).toList }
.map(processChunks)
.flatMap { Future.traverse(_)(f) }