Promises and Futures are kinda like complementary things.
You return a future that holds "eventually computed data". Using promise you can create a future, pass it somewhere else where other part of your code will know that it has to wait for it (by wait I don't mean block!) and by setting a value on the promise you will inject that "eventually computed data" so it's available.
What does it have to do with play?
Well, by using Action.async
your returning not a Response but a Response wrapped in a Future -> Future[Response].
Basically you could create a promise return the future to the caller and "complete" the promise somewhere else.
A good example is (taken from the documentation) :
def index = Action.async {
val futureInt = scala.concurrent.Future { intensiveComputation() }
val timeoutFuture = play.api.libs.concurrent.Promise.timeout("Oops", 1.second)
Future.firstCompletedOf(Seq(futureInt, timeoutFuture)).map {
case i: Int => Ok("Got result: " + i)
case t: String => InternalServerError(t)
}
}
The timeoutFuture is created using a promise that will have it's value set to "Oops" after a second. If the intensiveComputaion is finished first it will be passed to the caller.