【问题标题】:Why do futures get called in a for comprehension if they aren't used?如果未使用期货,为什么会在理解中调用期货?
【发布时间】:2014-03-30 00:26:31
【问题描述】:

我正在尝试实现一个将请求缓存到外部 API 的系统。如果响应在缓存中,则不应向外部站点发出请求。

我有两种方法:

// Check to see if the response is in the database
def checkCache(searchParameters: JsValue): Future[Option[JsValue]]

// Call the external API and get the JSON response
def getResponse(path: String): Future[JsValue]

然后我尝试执行以下操作:

val json: Future[JsValue] = for {
  databaseJson <- checkCache(searchParameters)
  externalJson <- getResponse(path)
} yield databaseJson match {
  case None => externalJson
  case Some(x) => x
}

这可行,但始终向外部 API 发出请求,即使返回缓存结果也是如此。这显然不是我想要的,因为它很慢。

我该如何解决这个问题?

【问题讨论】:

    标签: scala playframework playframework-2.0 future scala-2.10


    【解决方案1】:

    for 理解映射未来,而不是其中的选项。你的代码会翻译成这个

    checkCache(searchParameters) flatMap { databaseJson =>
      getResponse(path) map { externalJson =>
        databaseJson match {
          case None => externalJson
          case Some(x) => x
        }
      }
    }
    

    所以你显然总是打电话给getResponse()

    你需要一些类似的东西(未经测试):

    checkCache(searchParameters) flatMap { databaseJson =>
      databaseJson match {
        case None => getResponse(path)
        case Some(x) => Future.successful(x)
      }
    }
    

    【讨论】:

    • 你可以写checkCache() flatMap { case None =&gt; ... case Some(x) =&gt; ...}
    • 对,只是想让它尽可能接近原始代码。随时将其添加到我的帖子中。
    【解决方案2】:

    这有点俗气,但仍然:

    checkCache(params) map (_.get) fallbackTo getResponse(path)
    

    也未测试。

    更新:

    我不喜欢None.get 的失败转换,但实际上这一点都不俗气,而是很自然。更自然:

    checkCache(params) filter (_.nonEmpty) map (_.get) fallbackTo getResponse(path)
    

    由于两个期货的不对称性,Some.get 现在只是一个疣(它们不是两个Option)。

    【讨论】:

    • 这个也可以,但对我来说有点太神奇了
    【解决方案3】:

    你也可以试一试:

    val json: Future[JsValue] = for {
      databaseJson <- checkCache(searchParameters)
      json <- databaseJson.fold(getResponse(path))(js =>Future.successful(js))
    } yield json
    

    在精神上与 Marius Soutier 的回答类似,但在 for 理解中通过 fold 进行选项检查。

    【讨论】:

    • 在这种情况下,字母比精神更简洁。 (Future successful _) 更简洁。
    猜你喜欢
    • 1970-01-01
    • 2017-03-26
    • 2010-09-09
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 2014-08-08
    相关资源
    最近更新 更多