Scala flatMap' d未来行为

时间:2015-10-28 17:14:12

标签: scala future

在某种程度上,期货似乎很好。他们以简单易用的方式简化多线程,拥抱它们让我更喜欢Scala编码。

那就是说,我在理解中找到了一个漏洞。假设我们有一个功能:

def foo: Future[C] = {
  val f: Future[A] = ...
  val g: A => Future[B] = ...  // DB access maybe. Don't care about return type.
  val h: A => Future[C] = ...

  // Monads are great.
  f.flatMap { a =>
    g(a)  // Eval time? Return type?
    h(a)
  } 
}

问题

  1. fooh不依赖g的返回值。即使g没有,他们也会完成吗?也就是说,如果foo.map(...)尚未完成,h(a)会产生g的值吗?
  2. 这里g的返回类型是什么?它被处理为Unit,因为它被忽略了吗?

2 个答案:

答案 0 :(得分:4)

g的返回类型清楚地表示为Future[B],这并没有改变。你是正确的认识到这个价值被抛弃了。在未来[B]中进行的副作用仍然会发生,无论h创造的未来发生什么,它们都会发生。

我要做的是,为了强调这一点,就是以一种计算上相同的方式来编写它,但更清楚地表明这些事情正在发生:

f.foreach(g)
f.flatMap(h)

每当你看到foreach它应该触发"必须发生副作用",这对读者来说是一个重要的事情。

答案 1 :(得分:3)

我投了Stew的答案但是会补充一点,如果你关心g失败了,那么另一种写作方式是:

 f.flatMap{
   val ga = g(a)
   val ha = h(a)

   for{
     _ <- ga
     out <- ha
   } yield out
 }

这将在不同的主题中运行hg,而不会跳过h,但会保留g的错误。