Wonpyo Park Wonpyo Park - 1 month ago 6
Scala Question

Why do we need both Future and Promise?

As I know,

Future
is read-only and
Promise
is write-once data structure.

We need a
Promise
to complete a
Future


For example,

object Lie extends Throwable

val lie = Future { throw Lie }

val guess = Promise[String]()

lie.onComplete { case Success(s) => guess.success("I knew it was true!")
case Failure(t) => guess.failure("I knew it was lie")}
// return type: Unit

guess.future.map(println)
// res12: scala.concurrent.Future[Unit] = List()
// I knew it was lie!
// Requires Promise to chain Future with exception





But, I can't understand why we need to have both
Future
and
Promise


I guess
Promise
is required because of
Future.onComplete
signature

Since
Future.onComplete
return type is
Unit
,
Future
with possible exceptions cannot be chained

I assume
Promise
was introduced to overcome this limitation




But why not just change the signature of
Future.onComplete
?

Changing the return type of
Future.onComplete
as
Future[T]
will enable chaining on
Future
with exception

and then,
Future
does not need
Promise


For example, code above can be changed into

val lie = Future { throw Lie }

lie.onComplete {
case Success(s) => "I knew it was true!"
case Failure(t) => "I knew it was lie!"
}.map(println)

//onComplete return type is Future[String]





My question is

1) am I right? does
Future
not need
Promise
, If onComplete signature is changed from
Unit
to
Future[T]
?

2) Why Future and Promise are divided in the first place ?

UDPATE

Thanks to the repliers, Now I understand the purpose of Promise. It wasn't actually for
Future
chaining

If I may, can I ask you

Why
onComplete
returns
Unit
??

It can actually return
Future[T]
to enable chaining Future easily

For example

Future { throw Error }.onComplete {
case Success(s) => "Success"
case Failure(t) => throw Error
}.onComplete {
case Success(s) => "Success"
case Failure(t) => throw Error
}. ...

Answer

am I right? does Future not need Promise , If onComplete signature is changed from Unit to Future[T]?

You're mixing things up a little. Let's clarify.

A Future[T] represents a computation which will complete in the future. That is, you pass Future.apply a function which will execute on a thread assigned by some ExecutionContext you define.

Now, on the other hand, a Promise[T] is a way to create a Future[T], without actually creating a Future[T]. A good example for this would be the Future.successful method (which will internally consume Promise.successful):

def successful[T](result: T): Future[T] = Promise.successful(result).future

This requires no ExecutionContext and no queuing if any additional resources. It's merely a convenience wrapper that allows you to "artificially" create a Future[T].

Comments