[英]Dealing with Multiple Futures in Scala
我目前有一種基於Future[String]
更新Redis表的方法。
def update(key: String, timeStamp: Long, jsonStringF: Future[String], redisClient: RedisClient) = {
jsonStringF.map { jsonString =>
val historyKey = "history." + key
val tempKey = "temp." + key
val tran = redisClient.transaction()
tran.zadd(historyKey, (timeStamp, jsonString))
tran.del(tempKey)
val f = tran.exec()
f.onComplete {
case Success(suc) => dlogger.info(s"Updated $historyKey and deleted $tempKey successfully ....")
case Failure(ex) => dlogger.warn(s"Error updating tables", ex)
}
}
}
現在,我有兩個Future[String]
( jsonStringF1
和jsonStringF2
),我想更新兩個不同的表。
def update(key: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2: Future[String], redisClient: RedisClient) = {
....
}
我想用jsonStringF2
String
更新另一個表( "another." + key
)。 我怎樣才能做到這一點 ?
更新 :下面的代碼正確嗎?
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2: Future[String], redisClient: RedisClient) =
{
for {
a <- jsonStringF1
t <- jsonStringF2
historyKey = "history." + tableKey
anotherKey = "another." + tableKey +
tempKey = "temp." + tableKey
tran = redisClient.transaction()
_ = tran.zadd(historyKey, (timeStamp, a))
_ = tran.zadd(anotherKey, (timeStamp, t))
_ = tran.del(tempKey)
f = tran.exec()
} yield ()
}
您可以使用for
來收集多個期貨:
val f1: Future[String] = ...
val f2: Future[String] = ...
for {
a <- f1
b <- f2
} {
// Code to execute when both f1 and f2 complete
// a and b are available here
}
如您所描述的,您可以使用for循環
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2:Future[String], redisClient: RedisClient) = { for { a <- jsonStringF1 t <- jsonStringF2 } yield { val historyKey = "history." + tableKey val anotherKey = "another." + tableKey val tran = redisClient.transaction() tran.zadd(historyKey, (timeStamp, a)) tran.zadd(anotherKey, (timeStamp, t)) tran.del(tempKey) tran.exec() } }
作為替代方案,您還可以使用scala / async( https://github.com/scala/async )並像這樣編寫代碼
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2:Future[String], redisClient: RedisClient) = { async { val a = await(jsonStringF1) val t = await(jsonStringF2) val historyKey = "history." + tableKey val anotherKey = "another." + tableKey val tran = redisClient.transaction() tran.zadd(historyKey, (timeStamp, a)) tran.zadd(anotherKey, (timeStamp, t)) tran.del(tempKey) tran.exec() } }
這也將是非阻塞的。 異步有一點優勢,因為
異步塊被編譯為單個匿名類,而不是為每個生成器所需的每個閉包單獨的匿名類。
由於您只有2個期貨,因此可以將它們壓縮:
def update(tableKey: String, timeStamp: Long, jsonStringF1: Future[String], jsonStringF2:Future[String], redisClient: RedisClient) = {
val jsons = jsonStringF1.zip(jsonStringF2)
jsons map {
case (a, t) =>
val historyKey = "history." + tableKey
val anotherKey = "another." + tableKey
val tran = redisClient.transaction()
tran.zadd(historyKey, (timeStamp, a))
tran.zadd(anotherKey, (timeStamp, t))
tran.del(tempKey)
tran.exec()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.