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

Won*_*ark 4 jvm scala future 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 
Run Code Online (Sandbox Code Playgroud)


但是,我无法理解为什么我们需要同时拥有FuturePromise

我猜Promise是因为Future.onComplete签名所必需的

由于Future.onComplete返回类型是Unit,Future可能的例外情况不能链接

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


但为什么不改变签名Future.onComplete呢?

更改Future.onCompleteas 的返回类型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]
Run Code Online (Sandbox Code Playgroud)


我的问题是

1)我是对的吗?也Future没有必要Promise,如果签名的onComplete从改变UnitFuture[T]

2)为什么将未来和承诺分开?

UDPATE

感谢回复者,现在我理解了Promise的目的.它实际上并不是用于Future链接

如果可以,我可以问你

为何onComplete回归Unit

它实际上可以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 
}. ... 
Run Code Online (Sandbox Code Playgroud)

Vik*_*ang 6

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

A Future表示当前可用或可能不可用的.

A Promise代表在某些时候提供这种价值的义务.

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

  • 当Future是一个参数时,它是在某个时刻具有某个值的请求,当它被用作返回类型时,它是一个当前可用的响应.

  • 当Promise是一个参数时,它是在某个时刻产生某些价值的责任的"消费",当它被用作回报类型时,它是在某个时刻产生价值的责任的"产生".

总而言之,能够推断能力,特别是在异步甚至并发程序中,是非常有价值的.

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

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

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


Yuv*_*kov 2

我对吗?不需要,如果签名从Unit改为Future[T] FuturePromiseonComplete

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

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

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

def successful[T](result: T): Future[T] = Promise.successful(result).future
Run Code Online (Sandbox Code Playgroud)

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