Futureをマスターする -コンパニオンオブジェクト操作-

コンパニオンオブジェクトFutureの全メソッド網羅いきます。

# シリーズ目次
[はじめに](http://qiita.com/mtoyoshi/items/08766629abea6eb8e4bc)
[コンパニオンオブジェクト操作](http://qiita.com/mtoyoshi/items/297f6acdfe610440c719)
[インスタンス操作](http://qiita.com/mtoyoshi/items/f68beb17710c3819697f)
[おまけ](http://qiita.com/mtoyoshi/items/cc34d95bdffb6ce012e9)
[Futureにハマる](http://qiita.com/mtoyoshi/items/78912722f8ccc13d80f6)

# Futureの単独生成&並列実行

## apply (※要ExecutionContext、別スレッドでの実行)
通常はapplyを明示的に呼ぶことはないでしょう。以下のように使用。

```scala
val f: Future[String] = Future {
  "hello"
}
```

なお、ネットでよく見るサンプルも[公式ドキュメント](http://docs.scala-lang.org/overviews/core/futures.html)もfuture{...}で生成しているものばかりなのですが、Scala2.11から[scala.concurrent](http://www.scala-lang.org/api/current/#scala.concurrent.package)のfutureメソッドはdeprecated扱いになっており、代わりにFutureを使うよう記述されています。
よって本記事ではfutre{ ... }は使用せずFuture{ ... }で統一しています。

# Futureの単独生成（実行済みFuture）
実行済みFutureを作成するため並列実行は行われない。よってAwaitによる待ちは不要。
当然、valueで呼び出してもNoneではなく全てSomeである。

## successful
scala.util.Successなvalueを生成。

```scala
val f: Future[Int] = Future.successful(100)
```

## failed
scala.util.Failureなvalueを生成。

```scala
val f: Future[String] = Future.failed{ new Exception("error in future") }
```

## fromTry
TryからFutureを作成する。

```scala
val f: Future[String] = Future.fromTry(Try{ 
  if (...) "hello" else throw new Exception("error in f") 
})
```

# Futureの複数生成&複数の並列実行

## traverse (※要ExecutionContext、別スレッドでの実行)
TraversableOnceなものからFutureを複数生成&実行。
5だけ意図的に遅らせているが、結果は終わった順ではなく、traverseで処理した順に返ってくる。
よってこの結果は1,2,3,4,5,6,7,8,9,10,11,12となる。

```scala
  val f: Future[List[Int]] = Future.traverse((1 to 12).toList) { i =>
    Future {
      println(s"start: $i")
      if (i == 5) Thread.sleep(5000) else Thread.sleep(1000)
      println(s"end: $i")
      i
    }
  }
  f.onSuccess{ case result: List[Int] => println(result.mkString(",")) }

  Await.ready(f, Duration.Inf)
```

4コアCPUのMacBookの環境で実行すると、4つずつ同時に処理されることが確認できる。

## sequence (※要ExecutionContext、別スレッドでの実行)
traverseの簡易版で、引数にFutureのTraversableOnceを取る。
結果については上記と同様。

```scala
  val futures: List[Future[Int]] = (1 to 12).toList.map { i =>
    Future {
      println(i)
      Thread.sleep(1000)
      i
    }
  }

  val f: Future[List[Int]] = Future.sequence(futures)
  f.onSuccess{ case result => println(result.mkString) }

  Await.ready(f, Duration.Inf)
```

# Futureの複数生成&複数並列実行&特定の条件を満たしたFutureをひとつ返す

## firstCompletedOf (※要ExecutionContext、別スレッドでの実行)
並列実行するFutureの中で最初に終わったFutureをひとつ返す。
3で例外が出るが、4の方が先に終わるのでonSuccessコールバックのほうが呼ばれる。なお、3と4の処理を入れ替えれば、onFailureコールバックのほうが呼ばれる。

```scala
  val futures: Seq[Future[Int]] = Seq(
    Future{ Thread.sleep(3000); 1 },
    Future{ Thread.sleep(2000); 2 },
    Future{ Thread.sleep(1000); throw new Exception("error in 3") },
    Future{ Thread.sleep(500); 4 })

  val f = Future.firstCompletedOf(futures)
  f.onSuccess{ case result: Int => println(result) }
  f.onFailure{ case t => println(t.getMessage()) }

  Await.ready(f, Duration.Inf)
```

## find (※要ExecutionContext、別スレッドでの実行)
第一引数にFutureのTraversableOnce、第二引数にBooleanを返す関数を指定し、それを満たす最初のFutureが返る。
以下の例の場合は最初に処理が終わるのは4だが、条件は奇数のものなのでこの場合は3が返る。
なお、例外が起きるFutureがある場合の振る舞いはfirstCompletedOfと同じ。


```scala
  val futures: Seq[Future[Int]] = Seq(
    Future{ Thread.sleep(3000); 1 },
    Future{ Thread.sleep(2000); 2 },
    Future{ Thread.sleep(1000); 3 },
    Future{ Thread.sleep(500); 4 })

  val f = Future.find(futures){ _ % 2 == 1 }
  f.onSuccess{ case result: Option[Int] => println(result.get) }

  Await.ready(f, Duration.Inf)
```

# Futureの複数生成&複数並列実行&全てのFutureの結果のまとめあげ

# fold (※要ExecutionContext、別スレッドでの実行)
各Futureの結果を畳み込み演算する。
以下は初期値10から初めて、畳み込んだ結果、20が返ってくる。
なお、ひとつでも例外が起きるFutureがいるとonFailureコールバックが呼ばれる。

```scala
  val futures: Seq[Future[Int]] = Seq(
    Future{ Thread.sleep(3000); 1 },
    Future{ Thread.sleep(2000); 2 },
    Future{ Thread.sleep(1000); 3 },
    Future{ Thread.sleep(500); 4 })

  val f = Future.fold(futures)(10){ (total, v) => total + v }
  f.onSuccess{ case result: Int => println(result) }

  Await.ready(f, Duration.Inf)
```

# reduce (※要ExecutionContext、別スレッドでの実行)
初期値なしのfold。0から始まるので結果は10となる。
なお、ひとつでも例外が起きるFutureがいるとonFailureコールバックが呼ばれる。

```scala
  val futures: Seq[Future[Int]] = Seq(
    Future{ Thread.sleep(3000); 1 },
    Future{ Thread.sleep(2000); 2 },
    Future{ Thread.sleep(1000); 3 },
    Future{ Thread.sleep(500); 4 })

  val f = Future.reduce(futures){ (total, v) => total + v }
  f.onSuccess{ case result: Int => println(result) }

  Await.ready(f, Duration.Inf)
```

# 応用：組み合わせ
10個のFutureを実行するf1とf2を作成し、それらの結果をfoldで足し合わせるfを定義。
全てが終わったら数字を足し合わせて結果を出力する。結果は220。

```scala
  val f1: Future[List[Int]] = Future.traverse((1 to 10).toList) { i =>
    Future { Thread.sleep(i * 100); i }
  }
  val f2: Future[List[Int]] = Future.traverse((11 to 20).toList) { i =>
    Future { Thread.sleep(i * 100); i }
  }

  val f: Future[List[Int]] = Future.fold(List(f1, f2))(List(10)){ (total, v) => v ++: total }
  f.onSuccess{ case result: List[Int] => println(result.sum) }

  Await.ready(f, Duration.Inf)
```

# メソッドコンプリート状況
基本編と生成編を終えてメソッドコンプリート率は現時点では以下となりました。

trait Awaitable: 5/5
trait Future: 3/16
object Future: 10/10