为什么我们需要 Future 和 Promise?

Why do we need both Future and Promise?

据我所知,Future是只读的,Promise是一次性写入的数据结构。

我们需要一个Promise来完成一个Future

例如,

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 


但是,我不明白为什么我们需要同时拥有 FuturePromise

我想 Promise 是必需的,因为 Future.onComplete 签名

因为 Future.onComplete return 类型是 UnitFuture 可能有例外,不能链接

我假设引入 Promise 是为了克服这个限制


但为什么不直接更改 Future.onComplete 的签名呢?

Future.onComplete 的 return 类型更改为 Future[T] 将在 Future 上启用链接,例外情况是

然后,Future不需要Promise

比如上面的代码可以改成

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]


我的问题是

1) 我说得对吗? Future 不需要 Promise 吗,如果 onComplete 签名从 Unit 更改为 Future[T]

2) 为什么 Future 和 Promise 首先分开?

UDPATE

感谢回复者,明白Promise的用意了。它实际上不是 Future 链接

如果可以,我可以问你吗

为什么 onComplete returns Unit ??

它实际上可以 return Future[T] 轻松启用链接 Future

例如

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

没有

Future无法涵盖 Promise 的用例。 Promise 有它自己的价值。您不能将 Future 替换为 Promise.

Future 表示稍后可用的计算。未来执行完成后,您可以使用 onComplete 获得结果,您可以使用 mapflatMaprecoverrecoverWith.[=36 组合期货=]

Promise is one time write container, clients can subscribe to the container. When subscribed client gets a future to wait until value is written into that container called promise.

未来是只读的

You cannot use future as one time write container. You can only read from future.

但是Promise不一样。

What if you want to give user something, which you do not have right now but you think you will have it soon ?

这意味着您向用户承诺您现在没有的东西。

所以你想让用户一直等到你拿到你要给用户的东西。那就是当你做 p.future 并生成一个未来,以便用户可以使用未来等待结果。

一旦你得到了你承诺给用户的结果,当坏事发生时,你通过让未来成为 successfailure 来给用户(即通过做 p.complete).

Even if onComplete return type is changed to Future[T]. Future cannot act like or serve purpose of Promise.

使用 Future 伴随对象创建 Future

也可以使用 Future.apply 创建未来。在这种情况下,一旦 future 中的计算完成,future created 就会完成。

Future is used to subscribe to the result of the time-consuming computation, whereas Promise can be a publish and subscribe model.

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

你把事情搞混了。让我们澄清一下。

一个Future[T]表示一个计算将在未来完成。也就是说,您传递 Future.apply 一个函数,该函数将在您定义的某些 ExecutionContext 分配的线程上执行。

现在,另一方面,Promise[T] 是一种 创建 Future[T] 的方法,而无需实际创建 Future[T]。一个很好的例子是 Future.successful 方法(它将在内部消耗 Promise.successful):

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

这不需要 ExecutionContext,如果有任何额外资源也不需要排队。它只是一个方便的包装器,允许您 "artificially" 创建一个 Future[T].

Future.apply[T](block: => T): Future[T]Future.unit.map(_ => block)[1]

的语法糖

A Future 表示一个 ,它可能 当前 可用也可能不可用。

一个Promise表示在某个时候提供这样一个值的义务

Future(用于读取)和 Promise(用于写入)具有单独的实体意味着很容易推理功能:

  • 当 Future 是一个参数时,它是一个在某个时刻具有某个值的请求,当它被用作一个return类型,这是一个当前可能不可用的响应。

  • 当 Promise 是参数时,它是 "consumption" 负责在某个时刻产生一些值,当它被用作 return 类型时它是"production" 在某个时候产生价值的责任。

总而言之,能够推理能力,尤其是在异步甚至并发程序中,是非常有价值的。

大多数时候不需要使用 Promises,因为它由 Future-combinators 透明地处理——但是当与第三方软件或网络库集成时,它会非常有用。

有关 Scala 2.12 中有趣的新功能的更多信息,请查看 here

1:其中 Future.unit 定义为: val unit: Future[Unit] = Future.successful(())