【问题标题】:Dealing with Multiple Futures in Scala在 Scala 中处理多个期货
【发布时间】:2014-08-27 03:39:59
【问题描述】:

我目前有一个基于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 ()
  }

【问题讨论】:

    标签: scala future


    【解决方案1】:
    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. 作为 for 的替代方案,您还可以使用 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】:

      您可以使用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
      }
      

      【讨论】:

        【解决方案3】:

        由于您只有 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()
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-01-24
          • 2017-09-30
          • 1970-01-01
          • 2014-01-10
          • 1970-01-01
          • 2017-03-26
          • 2015-08-13
          相关资源
          最近更新 更多