scala - 在 Scala 中处理多个 Future

标签 scala future

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

最佳答案

  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()
        }
    }
    

这也将是非阻塞的。 异步有一点优势,因为

async blocks are compiled to a single anonymous class, as opposed to a separate anonymous class for each closure required at each generator.

关于scala - 在 Scala 中处理多个 Future,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25518577/

相关文章:

multithreading - 如何在Scala中理解 “new {}”语法?

scala - 如何将这三个类轮写成一个类轮?

mysql - "Hello World"使用 MySQL 的 Slick 2.0 示例

java - 不调用 Future.get 会导致任何问题吗?

c++ - "Flatten"嵌套 future

c++ - 是什么导致了 std::async 中的数据竞争?

java - 构建器模式和 DSL 是等效的——还是更具表现力?

scala - 尝试编译播放模板项目时 Unresolved 依赖项 : sbt-plugin;2. 7.0

java - springkafka-template 发送方法回调未注册的可能性

java - future - 线程未能停止