我对Scala很新,请耐心等待。我有一大堆期货包裹在一个大数组中。期货已经通过几TB数据完成了他们的努力工作,在我的应用程序结束时,我想结束所有期货的结果,以便我能很好地呈现它们。
我拥有的期货集合属于以下类型:
Array[Future[List(String, String, String)]]
到目前为止,我所阅读的关于for-comprehension的所有内容都表明
val test: Seq[Seq[List[String]]] = Seq(Seq(List("Hello", "World"), List("What's", "Up")))
val results = for {
test1 <- test
test2 <- test1
test3 <- test2
} yield test3
结果
results: Seq[String] = List(Hello, World, What's, Up)
按照同样的逻辑,我的意图是这样做,因为我最近发现Option,Try,Failure和Success可以被视为集合:
val futures = { ... } // Logic that collects my Futures
// futures is now Array[Future[List(String, String, String)]]
val results = for {
// futureSeq as Seq[List(String, String, String]
futureSeq <- Future.sequence(futures.toSeq)
// resultSet as List(String, String, String)
resultSet <- futureSeq
} yield resultset
但这不起作用。我似乎收到以下编译错误:
错误:(78,15)类型不匹配;
found:Seq [List(String,String,String)]
必需:scala.concurrent.Future [?]resultSet&lt; - futureSeq ^
带有要求的部分: scala.concurrent.Future [?] 让我完全失望。我完全不明白为什么那里需要一个未来。
我通过REPL检查了所有对象的类型,通过调试和使用IntelliJ的类型检查。他们似乎证实我并不只是对我的类型感到困惑。
在任何人提到之前,是的,我知道for-comprehension是一堆地图,flatMaps和withFilters的语法糖。
答案 0 :(得分:2)
for
- 理解如何去除对flatMap
和map
的调用的详细信息非常重要。这段代码:
for {
futureSeq <- Future.sequence(futures.toSeq)
resultSet <- futureSeq
} yield resultset
或多或少地变成这样的东西:
Future.sequence(futures.toSeq).flatMap(futureSeq => futureSeq)
flatMap
上的Future
需要一个返回Future
的函数,但您已经给它一个返回Seq[List[(String, String, String)]]
的函数。
一般情况下,你不能在for
中混合类型 - 理解(Option
在序列理解中是一种由隐式转换支持的异常)。如果你的未来有<-
箭头,那么<-
箭头的其他所有箭头都需要来自未来。
你可能想要这样的东西:
val results: Future[Seq[(String, String, String)]] =
Future.sequence(futures.toSeq).map(_.flatten)
然后你可以使用这样的东西:
import scala.concurrent.Await
import scala.concurrent.duration._
Await.result(results.map(_.map(doSomethingWithResult)), 2.seconds)
同步显示结果(阻塞直至完成)。