简体   繁体   English

为什么我们需要未来和承诺?

[英]Why do we need both Future and Promise?

As I know, Future is read-only and Promise is write-once data structure. 据我所知, Future是只读的, Promise是一次写入数据结构。

We need a Promise to complete a Future 我们需要一个Promise来完成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 但是,我无法理解为什么我们需要同时拥有FuturePromise

I guess Promise is required because of Future.onComplete signature 我认为PromiseFuture.onComplete签名所必需的

Since Future.onComplete return type is Unit , Future with possible exceptions cannot be chained 由于Future.onComplete返回类型为Unit ,因此无法链接可能有异常的Future

I assume Promise was introduced to overcome this limitation 我认为Promise是为了克服这个限制而引入的


But why not just change the signature of Future.onComplete ? 但为什么不改变Future.onComplete的签名呢?

Changing the return type of Future.onComplete as Future[T] will enable chaining on Future with exception Future.onComplete的返回类型更改为Future[T]将启用Future与异常链接

and then, Future does not need Promise 然后, Future不需要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? 1)我是对的吗? does Future not need Promise , If onComplete signature is changed from Unit to Future[T] ? Future是否需要Promise ,如果onComplete签名从Unit更改为Future[T]

2) Why Future and Promise are divided in the first place ? 2)为什么将未来与承诺分开?

UDPATE UDPATE

Thanks to the repliers, Now I understand the purpose of Promise. 感谢回复者,现在我理解了Promise的目的。 It wasn't actually for Future chaining 它实际上并不适用于Future链接

If I may, can I ask you 如果可以,我可以问你

Why onComplete returns Unit ?? 为什么onComplete返回Unit

It can actually return Future[T] to enable chaining Future easily 它实际上可以返回Future[T]以轻松实现链接Future

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 
}. ... 

Future.apply[T](block: => T): Future[T] is syntactic sugar for Future.unit.map(_ => block) [1] Future.apply[T](block: => T): Future[T]Future.unit.map(_ => block)句法糖Future.unit.map(_ => block) [1]

A Future represents a value which may or may not be currently available. Future代表当前可用或不可用的

A Promise represents the obligation to provide such a value at some point . Promise代表了在某些时候提供这种价值的义务。

Having separate entities for Future (for reads) and Promise (for writes) means that it is easy to reason about capabilities: Future (用于读取)和Promise (用于写入)分开的实体意味着很容易推断出功能:

  • When a Future is a parameter, it is a request to have some value at some point and when it is used as a return type, it's a response which may not be currently available. 当Future是一个参数时,它是在某个时刻具有某个值的请求,当它被用作返回类型时,它是一个当前可用的响应。

  • When a Promise is a parameter, it is the "consumption" of responsibility of producing some value at some point, and when it is used as a return type it is the "production" of responsibility to produce the value at some point. 当Promise是一个参数时,它是在某个时刻产生某些价值的责任的“消费”,当它被用作回报类型时,它是在某个时刻产生价值的责任的“产生”。

All in all, being able to reason about capabilities, especially in asynchronous, or even concurrent programs, is extremely valuable. 总而言之,能够推断能力,特别是在异步甚至并发程序中,是非常有价值的。

Most of the time Promises need not be used, since that is transparently handled by the Future-combinators—but when integrating with third party software or networking libraries it can be extremely useful. 大多数时候Promise不需要使用,因为它由Future-combinators透明地处理 - 但是当与第三方软件或网络库集成时,它可能非常有用。

For more information about interesting new features in Scala 2.12, have a look here . 有关Scala 2.12中有趣的新功能的更多信息,请查看此处

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

am I right? 我对吗? does Future not need Promise , If onComplete signature is changed from Unit to Future[T]? Future是否需要Promise ,如果onComplete签名从Unit更改为Future [T]?

You're mixing things up a little. 你把事情搞混了。 Let's clarify. 让我们澄清一下。

A Future[T] represents a computation which will complete in the future. Future[T]代表将在未来完成的计算。 That is, you pass Future.apply a function which will execute on a thread assigned by some ExecutionContext you define. 也就是说,您将Future.apply传递Future.apply一个函数,该函数将在您定义的某些ExecutionContext指定的线程上ExecutionContext

Now, on the other hand, a Promise[T] is a way to create a Future[T] , without actually creating a Future[T] . 现在,另一方面, Promise[T]是一种创建Future[T] ,而不是实际创建Future[T] A good example for this would be the Future.successful method (which will internally consume Promise.successful ): 一个很好的例子是Future.successful方法(它将在内部使用Promise.successful ):

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

This requires no ExecutionContext and no queuing if any additional resources. 如果有任何其他资源,这不需要ExecutionContext ,也不需要排队。 It's merely a convenience wrapper that allows you to "artificially" create a Future[T] . 它只是一个方便的包装器,允许你“人工”创造一个Future[T]

No. 没有。

Future cannot cover the use cases of Promise . Future不能涵盖Promise的用例。 Promise has its own value. Promise有其自身的价值。 You cannot replace Future with Promise . 你无法用Promise取代Future

Future represents a computation which is available at a later point of time. Future表示稍后可用的计算。 You can get the result using onComplete once the future execution is complete and you can compose futures using map , flatMap , recover and recoverWith . 一旦未来的执行完成,你可以使用onComplete获得结果,你可以使用mapflatMaprecoverrecoverWith来组合recoverWith

Promise is one time write container, clients can subscribe to the container. Promise是一次性写入容器,客户端可以订阅容器。 When subscribed client gets a future to wait until value is written into that container called promise. 当订阅客户端获得未来等待,直到将值写入名为promise的容器中。

Future is read-only 未来是只读的

You cannot use future as one time write container. 您不能将future用作一次性写入容器。 You can only read from future. 你只能从将来读。

But Promise is different. Promise是不同的。

What if you want to give user something, which you do not have right now but you think you will have it soon ? 如果你想给用户一些你现在没有的东西,但你认为你会很快拥有它怎么办?

That means you are promising user something which you do not have right now. 这意味着您承诺用户现在没有的东西。

So you want to keep the user waiting till you have the thing which you will give it to user. 因此,您希望让用户等待,直到您拥有将其提供给用户的内容。 Thats when you do p.future and generate a future so that user can wait for the result using the future. 这就是当你进行p.future并产生一个未来,以便用户可以等待未来的结果。

Once you have the result which you promised to give the user, You give to user by making the future a success or failure when something bad happens (ie by doing p.complete ). 一旦你得到了你承诺给用户的结果,你就可以通过在发生不良事件时使未来successfailure (即通过做p.complete )来给用户。

Even if onComplete return type is changed to Future[T] . 即使onComplete返回类型更改为Future[T] Future cannot act like or serve purpose of Promise . Future不能表现或服务于Promise目的。

Creating future using Future companion object 使用Future伴侣对象创建未来

Future can be created by using Future.apply also. Future也可以通过使用Future.apply来创建。 In this case future created would be complete once the computation inside the future finishes. 在这种情况下,一旦未来的计算完成,未来创建的将是完整的。

Future is used to subscribe to the result of the time-consuming computation, whereas Promise can be a publish and subscribe model. Future用于订阅耗时计算的结果,而Promise可以是发布和订阅模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM