2016-09-11 6 views
2

私は、コードを同期型から非同期型に移行しています。問題はかなりシンプルです。一連の関数を呼び出し、最初の関数で停止してエラーのない結果を返します(その値を返す、そうでなければ最後に計算した値)。別のスカラ先物構成パズル

しかし、関数が非同期(Future [Int]を返す)になると、私は正しい呼び出しを得ることができません。例えば、

def ffind(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = { 
    if (ffs.isEmpty) result 
    else ffind(ffs.tail, ffs.head()) 
} 

は素晴らしい作品が、それは関係なく、戻り値の、すべての機能を評価します。しかし、何かのように:

def findBad(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = { 
    if (ffs.isEmpty) result 
    else { 
     ffs.head() map { res => 
     if (res != 0) res 
     else findBad(ffs.tail, Future(res)) 
     } 
    } 
} 

はチェックしません。助言がありますか?関数の各呼び出しが高価であると仮定することができます。そのため、シーケンス内の最初の「成功」呼び出しの後でも、何も2回呼び出されることはありません。 Future[Int]を返しfindBadが、マッピングresfindBadの呼び出しにFuture[Future[Int]]につながる:それは型チェックをしない理由TIA

+0

こんにちは、これは解決されましたか? – slouc

+0

はい、申し訳ありませんが、質問を更新することができませんでした。単に答えをアップアップしました。とても有難い! –

+0

私は強迫しているので、私はちょうどクリーンアップしています。私の答えがあなたの問題を解決したかどうか、それを受け入れられたとマークするか、それとも不十分であるか、私はそれを削除します。 – slouc

答えて

1

がここにあります。 mapflatMapに変更する必要があります。今度は、FutureFutureを返すように、Futureresを最初の条件(res!= 0の場合)から折り返さなければならないことに注意してください。ここでは、コードです:ところで、あなたがそれらをすべて実行し、すべての残りの部分を無視し、最初の完了方返すようにしたい場合は

ffs.head() flatMap { res => 
    if (res != 0) Future.succesful(res) 
    else findBad(ffs.tail, Future(res)) 
} 

、それは少し異なる問題が(hereを参照)ですが、あなたはそれぞれの関数呼び出しが高価であると言います私はそれがあなたがしようとしていることを疑う。

+0

定数に 'Future.apply'を使用しないでください。これは' Future.successful'が設計したものです。 'Future(res)'は、結果が分からないかのようにスケジュールされ、実行されるため、追加の不要な作業を作成します。シグネチャには、暗黙のex:ExecutionContextも必要です。 – flavian

+0

私はこれを私が投稿したのと同じように考えましたが、このケースでは違いは実際には簡単ではないと私は編集を気にしませんでした。しかし、OK、ポイントは、変更されます。 – slouc