Scalaを初めて、scala.concurrent.Futureに慣れてなかったのであれこれメモ
ただ実行する。
scala> Future {
| Thread.sleep(3000)
| println("hey!!")
| }
res6: scala.concurrent.Future[Unit] = Future(<not completed>)
scala> hey!!
Futureの戻り値はFuture[Unit]になる。
戻り値を取得する。Successになってたら取得できる。
scala> val f = Future {
| Thread.sleep(10000)
| "hey!!"
| }
f: scala.concurrent.Future[String] = Future(<not completed>)
scala> f
res13: scala.concurrent.Future[String] = Future(<not completed>)
scala> f.value.get.get
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:349)
at scala.None$.get(Option.scala:347)
... 28 elided
scala> f
res15: scala.concurrent.Future[String] = Future(Success(hey!!))
scala> f.value.get.get
res16: String = hey!!
複数のFutureをまとめる。
scala> val f1 = Future {
| Thread.sleep(3000)
| "hey!!"
| }
f1: scala.concurrent.Future[String] = Future(<not completed>)
scala> val f2 = Future {
| Thread.sleep(3000)
| "what's up?"
| }
f2: scala.concurrent.Future[String] = Future(<not completed>)
scala> val i = for {
| r1 <- f1
| r2 <- f2
| } yield r1+r2
i: scala.concurrent.Future[String] = Future(<not completed>)
scala> i.value.get.get
res18: String = hey!!what's up?
Future[String]とかをFuture[Unit]にする(戻り値を捨てる)
scala> val f = Future {
| Thread.sleep(3000)
| val message = "hey!!"
| println(message)
| message
| }
f: scala.concurrent.Future[String] = Future(<not completed>)
scala> hey!!
scala> val r = for {
| r <- f
| } yield {}
r: scala.concurrent.Future[Unit] = Future(<not completed>)
リストでつかう。こうするとSeq[Future[Int]]になる。
scala> def len(input: String): Future[Int] = {
| Future {
| Thread.sleep(3000)
| input.length
| }
| }
len: (input: String)scala.concurrent.Future[Int]
scala> val l = Seq("hoge", "fuga", "piyo")
l: Seq[String] = List(hoge, fuga, piyo)
scala> val r = l.map(len(_))
r: Seq[scala.concurrent.Future[Int]] = List(Future(<not completed>), Future(<not completed>), Future(<not completed>))
Future[Seq[Int]]にしたいときはFuture.sequenceを使う
scala> val r2 = Future.sequence(r) r2: scala.concurrent.Future[Seq[Int]] = Future(<not completed>)