【问题标题】:Using Futures in Scala?在 Scala 中使用期货?
【发布时间】:2016-05-13 15:51:09
【问题描述】:

我正在尝试将数据库合并到我的 http 微服务中。

微服务有一个函数getValueFromInternet(val: Foo): Future[Value],我的微服务正在根据GET 请求调用它。现在,我希望它发生这样,一个函数getValue(val: Foo): Future[Value] 将首先查询一个数据库,如果数据库没有返回结果,调用getValueFromInternet。数据库查询返回一个Future[Seq[Value2]],我可以在其中使用函数将 Value2 转换为 Value。如果没有找到与该值对应的条目,则返回一个空的Vector

这是我迄今为止尝试过的:

def getValue(val: Foo): Future[Value] = {
  val resultFuture = db.getValue(val)
  // 1st attempt. Clearly wrong
  resultFuture onComplete {
    case Success(Vector()) => getValueFromInternet(val)
    case Success(vec) => convertValue2to1(vec.head)
  }
  // 2nd attempt. This is also wrong
  resultFuture match {
    case Future(Success(Vector())) => getValueFromInternet(val)
    case Future(Success(vec)) => convertValue2to1(vec.head)
  }
}

如果有任何帮助建议我如何做到这一点,我将不胜感激。 我已经独立实现了数据库和微服务,你可以找到它们herehere

【问题讨论】:

标签: scala future


【解决方案1】:

你必须使用flatMap,因为如果第一个操作没有返回结果,你想做的事情也会返回一个未来。

这在编译时尽可能接近您的代码。请注意,您不能在 scala 中使用名为 val 的标识符,因为这是一个关键字。

def getValue(v: Foo)(implicit ec: ExecutionContext): Future[Value] = {
  val resultFuture: Future[Seq[Value2]] = db.getValue(v)
  resultFuture.flatMap { vec =>
    if(vec.isEmpty)
      getValueFromInternet(v)
    else
      Future.successful(convertValue2to1(vec.head))
  }
}

【讨论】:

  • 您实际上可以,只需使用反引号 ;) val.
  • 感谢您的帮助。你认为这可以使用 recoverWith 吗?因为这看起来就像 recoverWith 所做的一样
  • @Łukasz,是的,我知道。我仍然不会推荐它。 @Yash Srivastav,不,recoverWith 用于恢复失败的未来。但是,空向量是数据库的成功结果,而不是失败。您还需要recoverWith 来处理真正的数据库故障(如果数据库不可用,则从互联网获取价值)。
  • 我也不建议这样做,但仍然可以。
猜你喜欢
  • 1970-01-01
  • 2020-01-20
  • 2019-07-05
  • 2016-11-05
  • 2018-06-15
  • 2015-08-08
  • 2016-05-02
  • 2020-07-17
  • 2019-03-23
相关资源
最近更新 更多