【问题标题】:Scala: How to combine methods that return a FutureScala:如何组合返回 Future 的方法
【发布时间】:2015-05-08 07:41:09
【问题描述】:

给定一个 Map 存储从 EUR/USD 到 BTC 的汇率...

val btcRates = Map("EUR" -> 0.0036, "USD" -> 0.0045)

...以及以下两种方法...

// returns a Future containing a Map of value to convert to BTC
def getAmounts = Future(Map("EUR" -> 500.0, "USD" -> 550.0, "CHF" -> 400))

// returns a Future containing the exchange rate for the specified currency
def getBtcRate(refCurrency: String) = Future(btcRates(refCurrency))

如何调用getAmounts,然后为Map 的每个元素返回调用getBtcRate 以将金额转换为BTC?以及如何将所有转换后的金额相加?

def getTotal: Future[Double] = {
  getAmounts.flatMap { _.map { case (currency, amount) =>
    getBtcRate(currency).flatMap { rate =>
      amount * rate // how do I sum this and how do I return the result?
    }
  }}
}

【问题讨论】:

  • 什么是ratesrefCurrency
  • 是的......对不起,他们是两个错别字......刚刚修正。
  • 我会将预期的输出与您的示例数据一起添加到此。另外,我不确定我是否会将Map 放入Future 中以获得getAmounts。这似乎不符合Future 的精神,Future 是一个“您可以为尚不存在的结果创建的占位符对象”。

标签: scala future


【解决方案1】:

我使用 for-comprehension 表示getTotal,因为它比flatmaps 的链更容易看:

  def getTotal: Future[Double] = for {
    amounts <- getAmounts
    totals <- Future.sequence(
      amounts.map { case (currency, amount) => 
        getBtcRate(currency).map(rate => amount * rate)
      }
    )
  } yield totals.sum

这样做是amountsgetAmounts 的结果(实际上这是flatmap 的主体)。然后,您通过为每个 currency 调用 getBtcRate 来映射该元组以创建期货序列。然后对这些期货中的每一个进行映射以获得总数。

现在您有一个 Iterable[Future[Double]] 并使用 Future.sequence 将其转换为 Future[Iterable[Double]]

现在您可以只生成 Iterablesum 它,生成所需的 Future[Double]

【讨论】:

  • 非常感谢...我错过了 Future.sequence 的东西 ;-)
猜你喜欢
  • 2023-03-06
  • 2015-03-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 2016-08-01
相关资源
最近更新 更多