簡體   English   中英

在Scala中處理多個期貨

[英]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]jsonStringF1jsonStringF2 ),我想更新兩個不同的表。

  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
}
  1. 如您所描述的,您可以使用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() } } 
  2. 作為替代方案您還可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM