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
?