Scala:如何组合 return 一个 Future 的方法

Scala: How to combine methods that return a Future

假设 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 的每个元素 returns 调用 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?
    }
  }}
}

我对 getTotal 使用了 for-comprehension,因为它比一连串的 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].