I've read the docs about map and flatMap and I understand that flatMap is used for an operation that accepts a Future parameter and returns another Future. What I don't fully understand is why I would want to do this. Take this example:
- User hits my webservice asking to "do stuff"
- I download a file (which is slow)
- I process the file (which is CPU intensive)
- Render the result
I understand that I would want to use a future to download the file but I have have two options re processing it:
val downloadFuture = Future {/* downloadFile */}
val processFuture = downloadFuture map {/* processFile */}
processFuture onSuccess { case r => renderResult(r) }
or
val downloadFuture = Future {/* download the file */}
val processFuture = downloadFuture flatMap { Future {/* processFile */} }
processFuture onSuccess { case r => renderResult(r) }
By adding debug statements (Thread.currentThread().getId) I see that in both cases download, process and render occur in the same thread (using ExecutionContext.Implicits.global).
Would I use flatMap simply to decouple downloadFile and processFile and ensure that processFile always runs in a Future even if it was not mapped from downloadFile?