Last active
December 13, 2015 17:09
-
-
Save sam/4945452 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import concurrent._ | |
import ExecutionContext.Implicits.global | |
// Sleep each for 10 seconds: | |
for { | |
result1 <- future { Thread.sleep(10000); 1 } | |
result2 <- future { Thread.sleep(10000); 2 } | |
} println(s"result1 -> $result1, result2 -> $result2") | |
// So that took about 20 seconds. for-comprehensions are a way to flatten loops. | |
// Each additional binding is an inner loop. To demonstrate: | |
for { | |
outer <- 1 to 10 | |
inner <- 1 to 10 | |
} yield s"$outer:$inner" | |
// What we want is parallel operation. Use Future.zip instead: | |
val result1 = future { Thread.sleep(10000); 1 } | |
val result2 = future { Thread.sleep(10000); 2 } | |
result1 zip result2 map { | |
case (r1, r2) => println(s"result1 -> $r1, result2 -> $r2") | |
} | |
// And you'll see the println in about 10 seconds now. | |
// Try pasting the two vals above into your REPL first. Count to 5. Then paste the zip -> map. | |
// Your output should print in about 5 seconds now. The futures start processing when they're | |
// defined. Not when you attempt to map the results. Makes sense right? If you want a database | |
// result, you want that thing to go off and start work immediately. Not wait until you actually | |
// need the results to print. Nice to see it in action though. | |
// You might guess at this point that the important thing is to make the call to the future to | |
// get it going. So you defined the vals above, you could still use a for-comprehension at this | |
// point and get mostly the same behavior: | |
for(r1 <- result1; r2 <- result2) println(s"result1 -> $r1, result2 -> $r2") | |
// Yes, it's calling flatMap on the first one, then chaining the second, but since our RHS values | |
// are Futures and not Collections, that doesn't matter a whole lot. The above is _almost_ | |
// equivilent to the following: | |
result1.flatMap { r1 => result2.map { r2 => println(s"result1 -> $r1, result2 -> $r2") } } | |
// A bit ugly though right? That's the point of for-comprehensions. Prettifying nested mapping. | |
// I said "almost", because the above returns the value (Future[Unit]). Our for-comprehension | |
// would do the same if we had written it with a yield: | |
for(r1 <- result1; r2 <- result2) yield println(s"result1 -> $r1, result2 -> $r2") | |
// Since we didn't care about the return value of println (which is Unit aka void), we just | |
// ignored it is all. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment