我正在尝试查询表,将查询的值存储在Scala Map中并返回同一张地图。 为此,我想出了以下代码:
def getBounds(incLogIdMap:scala.collection.mutable.Map[String, String]): Future[scala.collection.mutable.Map[String, String]] = Future {
var boundsMap = scala.collection.mutable.Map[String, String]()
incLogIdMap.keys.foreach(table => if(!incLogIdMap(table).contains("INVALID")) {
val minMax = s"select max(cast(to_char(update_tms,'yyyyddmmhhmmss') as bigint)) maxTms, min(cast(to_char(update_tms,'yyyyddmmhhmmss') as bigint)) minTms from queue.${table} where key_ids in (${incLogIdMap(table)})"
val boundsDF = spark.read.format("jdbc").option("url", commonParams.getGpConUrl()).option("dbtable", s"(${minMax}) as ctids")
.option("user", commonParams.getGpUserName()).option("password", commonParams.getGpPwd()).load()
val maxTms = boundsDF.select("minTms").head.getLong(0).toString + "," + boundsDF.select("maxTms").head.getLong(0).toString
boundsMap += (table -> maxTms)
}
)
boundsMap
}
为了从方法getBounds
接收值,我使用了方法onCompletion
,如下所示:
val tmsobj = new MinMaxVals(spark, commonParams)
val boundsMap = tmsobj.getBounds(incLogIds)
boundsMap.onComplete({
case Success(value) =>
case Failure(value) =>
})
我以前在Scala中进行过编码,但是我刚接触过Scala中的Futures
。谁能让我知道如何将getBounds
返回的值检索到val boundsMap
答案 0 :(得分:1)
您可以使用Awaits(不是最好的方法)
val boundsMap = Await.result(tmsobj.getBounds(incLogIds),Duration.Inf)
或者仅在需要时使用值
val boundsMap = tmsobj.getBounds(incLogIds)
booundsMap.map(value => Smth_To_Do(value))
答案 1 :(得分:1)
不建议从Future访问值,因为它违反了异步计算的目的。但是,在某些情况下,您可能正在处理旧代码,或者有些情况是从将来获取价值是前进的方向。为了解决这种情况,有两种方法
for ... in
因此,这里等待的是,它将等待10秒以完成getBounds将来。如果它在此时间内完成,则您具有该值,否则将在此处获得异常。这种方法的最大缺点是,它会阻塞当前的执行线程。
Await.result(getBounds, 10 seconds)
onComplete
所以onComplete要做的是注册一个回调函数,该函数将在将来完成时执行。这是比较安全的等待。 您可以参考Accessing value returned by scala futures了解更多详情。
我希望这能回答您的问题。