2016-08-10 4 views
0

ScaralaのFuturesの周りに脳をゆっくりと包み込み、私が解こうとしているレイヤーケーキを少し持ちます。Scala Futuresで迷子になる

DeferredResolversangria-graphql + akkaです。デモコードを盗まれました。

Future.fromTry(Try(
    friendIds map (id => CharacterRepo.humans.find(_.id == id) orElse CharacterRepo.droids.find(_.id == id)))) 

を追加し、独自の変更を加えました。鉱山は、他の俳優の何かを尋ねるのに対して彼らは、メモリ内の検索を行います。

Future.fromTry(Try(
    accountIds match { 
     case h :: _ => 
     val f = sender ? TargetedMessage(h) 
     val resp = Await.result(f, timeout.duration).asInstanceOf[TargetedMessage] 
     marshallAccount(resp.body) 

     case _ => throw new Exception("Not found") 
    } 
)) 

ここで関連作品は、私は、リストの最初の要素を選ぶ、私は他の場所だActorRefに送信して待つということです結果。これは機能します。私がやりたい何か、しかし、ここでは結果を待つが、これは動作しませんFuture

Future.fromTry(Try(
    accountIds match { 
     case h :: _ => 
     sender ? TargetedMessage(h) map { 
      case resp:TargetedMessage => marshallAccount(resp.body) 
     } 

     case _ => throw new Exception("Not found") 
    } 
)) 

として全体のことを返す必要がされていません。これが消費されている場合、代わりにタイプAccount機能marshallAccountの(戻り値の型のもので、それはタイプの約束だ。私が正しく理解していれば代わりにFuture[Account]の戻り値の型を有するので、それは、これはFuture[Future[Account]]

の種類を持っていますので、 ?どのように私はあなたが間違っているAPIメソッドを見ている

答えて

3

これを平らんFuture.fromTryをすぐに解決の未来を作成するために使用され、コールが実際に非同期ではないという意味に行くことができますFuture.fromTryの実装飛び込む:。。

def fromTry[T](result: Try[T]): Promise[T] = new impl.Promise.KeptPromise[T](result) 

お約束は基本的にはがすでに発生しているものですと同じように、これはちょうどFuture.successfulのように、これはちょうど正しい戻り値の型を保証するために使用されています。

戻り値の型がFuture[Future[Something]]の理由は、既に未来を返しているものを別の未来に戻そうとしているからです。

質問パターンは、sender ? TargetMessage(h)への道です俳優の何かを質問し、未来を返す結果を待っています。

これにアプローチするための正しい方法:

val future: Future[Account] = accountIds match { 
    case h :: _ => sender ? TargetedMessage(h) map (marshallAccount(_.body) 
    case _ => Future.failed(throw new Exception("Not found")) 
} 

は、基本的にはあなたが戻り値の型が一貫しておきたい場合は例外から失敗した未来を返すためにFuture.failedを使用する必要があります。 Futuresの詳細とアプリケーションロジックの記述方法については、this tutorialをご覧ください。

関連する問題