[解決済み] Scalaです。リスト[Future]からFuture[List]への変換は、失敗したFutureを無視する。
質問
任意の長さのFutureのリストをFuture of Listに変換する方法を探しています。私はPlayframeworkを使っているので、最終的に、私が本当に欲しいのは
Future[Result]
ですが、物事を単純化するために、単に次のように言ってみましょう。
Future[List[Int]]
通常の方法では、このように
Future.sequence(...)
となるのですが、一工夫が...。与えられたリストには通常10-20のフューチャーがあり、そのうちの1つが失敗することも珍しくありません(それらは外部のウェブサービスへのリクエストを行っています)。そのうちの1つが失敗した場合、それらすべてを再試行するのではなく、成功したものを取得してそれを返すことができればと思います。
例えば、以下のようにしてもうまくいきません。
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Success
import scala.util.Failure
val listOfFutures = Future.successful(1) :: Future.failed(new Exception("Failure")) ::
Future.successful(3) :: Nil
val futureOfList = Future.sequence(listOfFutures)
futureOfList onComplete {
case Success(x) => println("Success!!! " + x)
case Failure(ex) => println("Failed !!! " + ex)
}
scala> Failed !!! java.lang.Exception: Failure
例外だけを取得するのではなく、そこから1や3を引き出せるようにしたい。試しに
Future.fold
を使ってみましたが、これはどうやら
Future.sequence
を呼び出しているだけです。
よろしくお願いします。
どのように解決するのですか?
まず、どの先物も失敗していないことを確認するのがコツです。
.recover
はここであなたの味方です、あなたはこれを
map
と組み合わせることで、すべての
Future[T]
の結果を
Future[Try[T]]]
インスタンスに変換され、そのすべてが成功した先物となることが確実です。
note: あなたは
Option
または
Either
も同様ですが、ここでは
Try
は最もクリーンな方法です。
def futureToFutureTry[T](f: Future[T]): Future[Try[T]] =
f.map(Success(_)).recover { case x => Failure(x)}
val listOfFutures = ...
val listOfFutureTrys = listOfFutures.map(futureToFutureTry(_))
次に
Future.sequence
を使うと、先ほどと同じように
Future[List[Try[T]]]
val futureListOfTrys = Future.sequence(listOfFutureTrys)
次にフィルタリングします。
val futureListOfSuccesses = futureListOfTrys.map(_.filter(_.isSuccess))
必要であれば、具体的な失敗例も引き出せます。
val futureListOfFailures = futureListOfTrys.map(_.filter(_.isFailure))
関連
-
[解決済み] Scalaのオブジェクトとクラスの違い
-
[解決済み] 述語で配列を2つに分割するには?
-
[解決済み] RDDの内容を印刷するには?
-
[解決済み] 依存するメソッドタイプの説得力のある使用例とは?
-
[解決済み] IntelliJ IDEAで依存関係が変更された後、build.sbtから強制的に再ロードするには?
-
[解決済み] Scalaでは、'val a. = _' (アンダースコア)は具体的にどのような意味ですか?A = _' (アンダースコア)とはどういう意味ですか?
-
[解決済み] ネストした構造体をよりきれいに更新する方法
-
[解決済み] scalaの列挙を理解する
-
[解決済み] SBTが終了せずに実行を停止する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン