2013-07-18 8 views
34

私はスカラ先物の初心者です。スカラ先物の戻り値については疑問があります。スカラ先物から返された値へのアクセス

ので、Scalaの将来のための一般的な構文は、私は、このメソッドを呼び出し、他のいくつかの方法からList[Int]にアクセスする方法を知りたい

def downloadPage(url: URL) = Future[List[Int]] { 

} 

です。言い換えれば

val result = downloadPage("localhost") 

その後、何が将来の外にList[Int]を取得するためのアプローチすべきですか?

私はマップ・メソッドを使用してみましたが、あなたは、いくつかのタイムスパン指定された結果を取得するために完了するために、将来のために待機する必要があり、このsuccessfully.`

答えて

7

を行うことができなかったが、ここに働くだろう何か:

import scala.concurrent.duration._ 

    def downloadPage(url: URL) = Future[List[Int]] { 
    List(1,2,3) 
    } 

    val result = downloadPage("localhost") 

    val myListInt = result.result(10 seconds) 

あなたがFutureを使用している場合、理想的には、実行中のスレッドをブロックしたくないので、あなたはonComplete方法にあなたのFutureの結果を扱うあなたのロジック、このような何かを移動します:

を10
result.onComplete({ 
    case Success(listInt) => { 
     //Do something with my list 
    } 
    case Failure(exception) => { 
     //Do something with my error 
    } 
    }) 
+3

私のエラー }} ) は、いくつかの方法の一部となると私はlistInt値を返すようにしたいです。どうやってするか ? – user1822249

+0

future自身を返すか、完了するまでブロックします。 –

+0

あなたがあなたの代わりに直接、将来の結果を得るための 'Await'を使用する必要があり、Scalaの2.10で – Noah

20

成功のケース(listInt)=>私はlistIntを返したいと思いますが、その方法を理解することはできません。

のベストプラクティスは、あなたが値を返さないということです。代わりに、この値を必要とするすべての人に未来(またはmapflatMapなどで変換されたバージョン)を渡し、自分でonCompleteを追加することができます。

本当に返品する必要がある場合(たとえば、従来の方法を実装する場合)、唯一行うことができるのはブロックすること(例:Await.result)で、待つ時間を決定する必要があります。 (実際には、すべてのアクションが内側に非同期です)あなたがプレイFrameworkを使用している場合

、それは非同期アクションをサポートしています。

+1

あなたはブロッキングなしに未来の価値を返すことができません。私はスカラーの目的はもっと機能的な言語であると考えました。将来のコールバックがユニットを返す場合、それは副作用をサポートしていませんか?これを回避する方法はありますか? –

+0

"ブロックせずに将来の価値を返すことはできないのですか?"あなたはどうですか?値はまだ利用できません。 「将来のコールバックがユニットを返すなら、それは副作用をサポートしていないのですか?これを回避する方法はありませんか? 'map'、' flatMap'などを使用してください。 –

+0

私の特別な状況は、ユーザーセッションが有効かどうかを調べることです。そうすることで、セッションが有効かどうかをサーバーに要求します。私はFuturesを使用するPlay Framework WSライブラリを使用します。スレッドをブロックすることなく、isValidSessionメソッドからtrueまたはfalseを返すことができればいいだけです。 –

4

は、私はそれが2013年に頼まれたので、あなたはすでにこれを解決したが、多分私の答えは、他の誰かが助けることができると思います。非同期アクションを作成する簡単な方法はAction.async()です。この機能にはFuture[Result]を指定する必要があります。

Future[List[Int]]からFuture[Result]への変換は、Scalaのmap、flatMap、for-comprehensionまたはasync/awaitを使用して行うことができます。ここでは、Play Frameworkのドキュメントの例を示します。

import play.api.libs.concurrent.Execution.Implicits.defaultContext 

def index = Action.async { 
    val futureInt = scala.concurrent.Future { intensiveComputation() } 
    futureInt.map(i => Ok("Got result: " + i)) 
} 
2

私は将来を考えるように見つけた最良の方法は、いくつかの点で、あなたが望むものを含んでいますボックスです。未来の鍵は、箱を開けないことです。ボックスを強制的に開こうとすると、ブロックと悲しみにつながります。代わりに、Futureを別の大きなボックスに配置します。通常は、mapメソッドを使用します。

ここに、文字列を含むFutureの例を示します。未来が完了したら、コンソール。printlnは

import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

object Main { 

    def main(args:Array[String]) : Unit = { 
    val stringFuture: Future[String] = Future.successful("hello world!") 
    stringFuture.map { 
     someString => 
     // if you use .foreach you avoid creating an extra Future, but we are proving 
     // the concept here... 
     Console.println(someString) 
    } 
    } 
} 

と呼ばれています。この場合、mainメソッドを呼び出してから終了します。文字列のFutureは、グローバルExecutionContextによって提供され、Console.printlnを呼び出す作業を行います。これは素晴らしいことです。なぜなら、someStringがそこにあるとき、Console.printlnが呼び出されるときに制御をあきらめたとき、システムはそれ自身を管理させるからです。私たちは、オープンボックスを強制しようとするとconstrastでは、何が起こるか見て: - その親指をいじるスレッドを保つ - 私たちは戻ってsomeString得るまで

val stringFuture: Future[String] = Future.successful("hello world!") 
val someString = Future.await(stringFuture) 

をこのケースでは、我々は待つ必要があります。私たちは箱を開いたが、システムのリソースを手に入れなければならなかった。

2

あなたはそのようなことをすることができます。 Await.result方法で指定された待機時間は、それが実行にawaitableを取るよりも小さい場合、あなたはTimeoutExceptionを持って、あなたはエラー(またはその他のエラー)を処理する必要があります。私の問題は result.onComplete({ 場合成功(listInt)=> { //は私のリストと } ケースの失敗(例外)=> { //がして何かをする何かをするある

import scala.concurrent._ 
import ExecutionContext.Implicits.global 
import scala.util.{Try, Success, Failure} 
import scala.concurrent.duration._ 

object MyObject { 
    def main(args: Array[String]) { 

     val myVal: Future[String] = Future { silly() } 

     // values less than 5 seconds will go to 
     // Failure case, because silly() will not be done yet 
     Try(Await.result(myVal, 10 seconds)) match { 
      case Success(extractedVal) => { println("Success Happened: " + extractedVal) } 
      case Failure(_) => { println("Failure Happened") } 
      case _ => { println("Very Strange") } 
     }  
    } 

    def silly(): String = { 
     Thread.sleep(5000) 
     "Hello from silly" 
     } 
} 
関連する問題