斯卡拉期货的理解

时间:2016-11-13 02:27:31

标签: scala future for-comprehension

我试图绕过Scala,我想知道以下是什么:

a: a.o
        $(COMPILER) a.o -o a

期货是在理解中执行的,对吗?那么val fFuture: Future[Int] = Future { println("f called"); 3 } val gFuture: Future[Int] = Future { println("g called"); 4 } for { f <- fFuture g <- gFuture } yield f 在yield语句中做了什么?这只是意味着它可用吗?如果它在函数内部,那被认为是f吗?

3 个答案:

答案 0 :(得分:4)

期货开始在这里执行:

val fFuture: Future[Int] = Future { println("f called"); 3 }                                                                                                                    
val gFuture: Future[Int] = Future { println("g called"); 4 } 

因此两个执行都是并行开始的。但是,如果你不小心将Future{...}置于理解之中 - 它们将按顺序执行。

for-comprehension基本上订阅并将两个结果合并为一个Future。但是,在你的情况下,似乎第二个未来的结果被忽略了,这是没有意义的。有意义的代码:

for {
    f <- fFuture
    g <- gFuture
} yield f + g

此代码返回Future[Int](与示例中的代码相同)。如果你从这个未来中提取价值 - 你得到3 + 4 = 7。然而,它仍然不是最佳方法,因为您的计算是独立的,并且开发人员错误的概率(如上所述)使得它们顺序仍然很高,因此建议的独立计算方法是:

(fFuture zip gFuture) map {
  case (f, g) => f + g
}

此代码的引用是透明的,即使您将fFuture替换为Future{...} - 它仍然表现相同(如果Future - 它们将以并行方式执行,但它可能与其他并发原语不同)

for-comprehension在哪里才有意义?这里:

for {
    f <- Future{... 9}
    g <- if (f > 0) Future{...} else Future{...}
} yield g

由于g取决于此处的f - 无法并行运行,因此for提供了一种无阻塞的方式来组合多个Future s < / p>

答案 1 :(得分:1)

Scala期货受到热切评估,这意味着它们的价值会立即在一个单独的线程中计算。

当你运行依赖于未来结果的操作时,当前线程将阻塞等待直到它被评估。如果使用组合方法(如map或flatMap)转换Futures,则会获得另一个表示最终结果的Future(运行这些操作的代码不需要阻止)。

因此,在您的示例中,编译器将for comprehension视为以下表达式:

fFuture.flatMap(f => gFuture.map(g => f + g))

本身是另一个线程中计算的Future [Int]。

答案 2 :(得分:-2)

在你的场景中,你不必使用理解,你可以简单地使用OnComplete。

ffuture.OnComplete {
Case Success(result) => println(s"$result')
Case Failure(ex) => ex.printStackTrace
}

当你的未来依赖于其他未来时需要理解 像:

var result =  for {
        f <- fFuture
        g <- f
    } yield g

此后g将在f完成后解决, 并且产量将返回您返回的结果。在这种情况下,它将是Future [Int]。 有了收益率,你可以做类似的事情。

yield g+f

要阅读结果,您只需使用

即可
result.onSuccess or onComplete

对于期货,我发现这篇文章是最好的: http://alvinalexander.com/scala/concurrency-with-scala-futures-tutorials-examples

我会说是,这类似于函数中的返回值。 但这是为了理解语法,你不能使用return语句。 理解是一种更好的编写地图的方法。