5

I am leaning Scala Concurrency using Future and Promises.

I am not getting the point, what is the exact difference between completing the Future using Callback methods and using Promises?

Does it mean Future Callback methods are actually not completing the Future?Only using Promise we can complete the Future?

Also, I have seen many places like you can read from both Futures and Promises, but you can only write to Promises.

Shankar
  • 8,529
  • 26
  • 90
  • 159

3 Answers3

5

Futures are only completed on the end of an asynchronous computation:

val f: Future[List[Int]] = Future {
  makeSomeNumbers() //when this finishes, the Future is completed.
}

f onSuccess {
  case foo => println("I was completed when makeSomeNumbers finished")
}

Whereas Promises can produce a future that can be completed manually.

val p = Promise[String]()
val f = p.future

p success('hi') //when success is called, the Future is completed.

f onSuccess {
  case foo => println("I was completed because a Promise told me to do so")
}

The callback passed to onSuccess does not complete the Future, it only listens when the Future is completed and does something. In the case of Promises, you can call its success method to complete its associated Future.

Federico
  • 3,650
  • 4
  • 32
  • 45
4

You can not complete a Future.

A Future is supposed to be a computation and this computation (once started) completes when it does. You have no control over it after creating it. You can assign onComplete callback to it which will be fired when this future completes but you have no control over when it will.

If you want to have a Future whose completion you can control, you can Promise that Future like a politician. Now whether you complete that future with success or failure is up to you.

// lets promise an Int
val promise = Promise[Int]()

// Now... we also have a future associated with this promise
val future = promise.Future

// assign a callback which will be called when future completes
future.onComplete(
  case Success(i) => println("Future complete :: " + i)
  case Failure(ex) => println("Future failed :: " + ex.toString)
)

// Future by itself provides you no way to complete it

// if you want to complete this future, you can fulfil your promise
promise.complete(Try(10))
Aamir
  • 2,380
  • 3
  • 24
  • 54
sarveshseri
  • 13,738
  • 28
  • 47
  • @Sarvesh Kumar Singh : AFAIK, future itself not a computation, please refer http://stackoverflow.com/a/18961936/1907755 – Shankar Sep 01 '16 at 05:31
  • By computation... I mean a execution block independent of current thread. – sarveshseri Sep 01 '16 at 05:42
  • +1 for the link. I like the point "a future is a placeholder object for a value that may be become available at some point in time, asynchronously." Also that "futures are like subscribers to some data that may arrive at some point" while "promises give the control to the client to complete a future" – Samar Sep 01 '16 at 05:55
  • 1
    Both placeholder and computation are just a way to explain `Future` in a reasonable and conventional manner. You can say that `Future` represents an execution which may result in a certain type of result or that `Future` is a placeholder for a result value. You have `result`, `isCompleted`, `onComplete`, `onSuccess`, `onFailure`, `andThen` which are sensible if you talk about them as computations. And you also have `ready`, `map`, `flatMap`, `foreach` which are sensible if you consider them as placeholders for values. – sarveshseri Sep 01 '16 at 06:09
0

You don't actually complete Future, you just passing callback to trigger when in completes. You can use Promise to controll when callback will be triggered. Example from scala official docs:

val p = Promise[T]()
val f = p.future

val producer = Future {
  val r = produceSomething()
  p success r
  continueDoingSomethingUnrelated()
}

btw Future using Promises under the hood.

Murat Mustafin
  • 1,284
  • 10
  • 17