等待Scala中具有组合选项的期货列表
我必须从带有Scala的RESTAPI中获取给定列表中每个文件的问题列表。我想并行处理这些请求,并使用库来实现这一点。我的方法是从Java框架中调用的,我必须在这个方法的末尾等待所有未来的结果,以便将总体结果返回到框架。这是我的密码:等待Scala中具有组合选项的期货列表,scala,future,Scala,Future,我必须从带有Scala的RESTAPI中获取给定列表中每个文件的问题列表。我想并行处理这些请求,并使用库来实现这一点。我的方法是从Java框架中调用的,我必须在这个方法的末尾等待所有未来的结果,以便将总体结果返回到框架。这是我的密码: defetchresourceasjson(filePath:String):dispatch.Future[json4s.JValue] def extractLookupId(json:org.json4s.JValue):选项[字符串] def findLo
defetchresourceasjson(filePath:String):dispatch.Future[json4s.JValue]
def extractLookupId(json:org.json4s.JValue):选项[字符串]
def findLookupId(filePath:String):Future[选项[String]]=
for(json)
(f,findIssues(lookupId))//我想在这里生成一个元组(String,Seq[Issue])
}
}
Future.sequence(issuesByFile)onComplete{
case Success(x)=>finalResultPromise.Success(x)/(2)如何在此处返回x?
case Failure(x)=>/(3)如何从此处返回null?
}
//TODO将finalResultPromise转换为Java映射
}
这个代码片段有几个问题。首先,我没有得到我期望的issuesByFile
(1)的类型。如果findLookUpId
无法找到查找ID(即None
),我只想忽略它的结果。我在各种教程中读过Future[Option[X]]
在函数组合和Scala中的表达式中不容易处理。因此,我也很好奇正确处理这些问题的最佳实践是什么
第二,我不得不等待所有的未来完成,但不知道如何将结果返回给调用Java框架(2)。我可以在这里使用承诺来实现这一点吗?如果可以,我该怎么做
最后但并非最不重要的一点是,如果出现任何错误,我只想从返回null
,这是JavaFramework调用的,但不知道如何返回(3)
非常感谢您的帮助
谢谢,
Michael有几点:
- (1)中的第一个问题是,如果
findLookupId
返回None
,则您无法处理这种情况。您需要决定在这种情况下要做什么。整个过程失败?是否将该文件从列表中排除
- (1)中的第二个问题是,
findIssues
本身将返回一个Future
,您需要map
才能构建结果元组
- 有一个快捷方式可用于
map
和Future.sequence
:Future.transverse
- 如果您无法更改方法的结果类型,因为Java接口是固定的,并且无法更改以支持未来本身,那么您必须等待未来完成。请使用
Await.ready
或Await.result
执行此操作
考虑到所有这些因素,选择忽略找不到id的文件会导致以下代码:
// `None` in an entry for a file means that no id could be found
def entryForFile(file: String): Future[(String, Option[Seq[Issue]])] =
findLookupId(file).flatMap {
// the need for this kind of pattern match shows
// the difficulty of working with `Future[Option[T]]`
case Some(id) ⇒ findIssues(id).map(issues ⇒ file -> Some(issues))
case None ⇒ Future.successful(file -> None)
}
def thisIsCalledByJavaFramework(): java.util.Map[String, java.util.List[Issue]] = {
val issuesByFile: Future[Seq[(String, Option[Seq[Issue]])]] =
Future.traverse(getFilePathsToProcess)(entryForFile)
import scala.collection.JavaConverters._
try
Await.result(issuesByFile, 10.seconds)
.collect {
// here we choose to ignore entries where no id could be found
case (f, Some(issues)) ⇒ f -> issues
}
.toMap.mapValues(_.asJava).asJava
catch {
case NonFatal(_) ⇒ null
}
}
非常容易理解的解释和工作代码。谢谢!