Scala:如何组合返回Future的方法

时间:2015-05-07 22:47:52

标签: scala future

鉴于Map存储了从欧元/美元到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?
    }
  }}
}

1 个答案:

答案 0 :(得分:3)

我已经为getTotal使用了 for-comprehension ,因为它在眼睛上比flatmap链更容易:

  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的正文)。然后,通过为每个getBtcRate调用currency来映射该元组以创建一系列期货。然后映射每个期货以获得总数。

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

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