2016-11-13 7 views
0

私はスカラ座のまわりで私の頭をラップしようとしていると私は、次が何をするか思ったんだけど:Scalaの先物

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は何をしますか?それはただそれが利用可能であることを意味しますか?これが関数内にある場合、これはreturn valueと考えられますか?

+2

「未来」は 'for'の内部では実行されません。宣言されると(常に)実行され、 'for'を使用して構成されます。 – cchantep

+1

@cchantep技術的には、ExecutionContextが実行を決定したときにのみ実行されます。 –

+0

私は言っておくべきことは、宣言と、将来の宣言との間に宣言があるので、ECによって決定された一度に実行されるべきだったはずです。お互いに – cchantep

答えて

3

先物はここで実行し始めている:

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

だから、両方の実行を並行して開始されています。しかし、誤ってFuture{...}を内包の中に入れた場合、それらは順番に実行されます。

基本的には、2つの結果を1つのFutureにサブスクライブしてマージします。しかし、あなたのケースでは、2番目の未来の結果が無視されたように思えますが、これは意味がありません。

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

このコードは、Future[Int](例のコードと同じです)を返します。この未来から価値を引き出すなら、あなたは3 + 4 = 7になります。しかし、まだ彼らはシーケンシャルは依然として高いです作るあなたの計算は独立し、(前述の)開発者のミスの確率があるよう最善のアプローチではないですが、独立した計算のためにとてもお勧めのアプローチは、次のとおりです。

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

このコードはで参照透明ですそれはまだ(prallelで実行されようとしてFuture -they'reの場合には、それは他の並行処理プリミティブのために異なる場合があります)同じように動作します

for-comprehension実際に理にかなってどこに - あなたはFuture{...}fFutureを交換する場合でも、ということを意味?ここで:gとして

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

がここfに依存 - そうforは、熱心に評価されているいくつかのFuture

-2

あなたのシナリオでは、理解のために使用する必要はありません。単純にOnCompleteを使用できます。理解のために

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

あなたが他の将来に依存して、将来の(S)(S) を持っているときのように必要とされている:fが完了した後グラムの未来は 、解決され、歩留まりが返されます

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

ここあなたが戻ってきた結果が何であれ。この場合、それは未来[Int]になります。 利回りでは、次のようなことができます。

yield g+f 

あなたは、単に先物

result.onSuccess or onComplete 

を使用することができ、結果を読み取るために、私は最高の一つとして、この記事を見つけた: http://alvinalexander.com/scala/concurrency-with-scala-futures-tutorials-examples

私ははい、これはリターンに似ていると言うだろう関数の値。 これは理解の構文のためのものです。あなたはreturn文を使用することはできません。 理解のために地図を書くより良い方法です。

+0

あなたが嫌い​​な理由を説明できるなら、私は何か新しいことを学ぶでしょう。 – user2056463

1

Scalaの先物を構成する非ブロック方法を提供し、並行してこれらを実行する方法はありませんいますその値が別のスレッドでただちに計算されることを意味します。

将来の結果に依存する操作を実行すると、現在のスレッドは評価されるまで待機することになります。 MapやFlatMapなどのコンビネータメソッドを使用してFuturesを変換すると、最終結果を表す別のFutureが得られます(これらの操作を実行するコードはブロックする必要はありません)。

だからあなたの例では、理解のために、以下の式にコンパイラによって脱糖さ:自身が将来[INT]別のスレッドで計算され

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

を。

関連する問題