据我所知,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
但是,我无法理解为什么我们需要同时拥有Future
和Promise
由于Promise
签名
Future.onComplete
是必需的
由于Future.onComplete
返回类型为Unit
,Future
可能无法链接
我认为Promise
是为了克服这种限制而引入的
但为什么不改变Future.onComplete
的签名呢?
将Future.onComplete
的返回类型更改为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)为什么将未来和承诺分开?
UDPATE
感谢回复者,现在我理解了Promise的目的。 Future
链接
如果可以的话,我可以问你吗
为什么onComplete
会返回Unit
??
它实际上可以返回Future[T]
以便轻松启用链接
例如
Future { throw Error }.onComplete {
case Success(s) => "Success"
case Failure(t) => throw Error
}.onComplete {
case Success(s) => "Success"
case Failure(t) => throw Error
}. ...
答案 0 :(得分:6)
Future.apply[T](block: => T): Future[T]
是Future.unit.map(_ => block)
[1]
Future
表示值,可能当前 可用。
Promise
表示有义务在某个时间提供 。
为Future
(用于读取)和Promise
(用于写入)具有单独的实体意味着很容易推断出功能:
当Future是一个参数时,它是一个请求在某个时候有一些值,当它被用作一个返回类型时,它的响应可能不是目前可用。
当Promise是一个参数时,它就是"消费"在某些时候产生某些价值的责任,当它被用作回报类型时,它就是生产和#34;在某些时候产生价值的责任。
总而言之,能够推断功能,特别是在异步,甚至并发程序中,是非常有价值的。
大多数时候Promise不需要使用,因为它由Future-combinators透明地处理 - 但是当与第三方软件或网络库集成时,它可能非常有用。
有关Scala 2.12中有趣的新功能的更多信息,请查看here。
1:Future.unit
定义为:
val unit: Future[Unit] = Future.successful(())
答案 1 :(得分:2)
我是对的吗?如果Future
签名是Promise
,那么onComplete
不需要Future[T]
从单位改为未来[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
如果有任何其他资源,则不需要Future[T]
,也不需要排队。它只是一个方便的包装器,允许您“人工”创建TestCase
。
答案 2 :(得分:1)
没有
Future
无法涵盖Promise
的用例。 Promise
有自己的价值。您无法将Future
替换为Promise
。
Future
表示稍后可用的计算。未来执行完成后,您可以使用onComplete
获得结果,并且可以使用map
,flatMap
,recover
和recoverWith
撰写期货。
Promise是一次性写入容器,客户端可以订阅容器。当订阅客户端获得未来等待,直到将值写入名为promise的容器中。
未来是只读的
您不能将future用作一次性写入容器。你只能从将来读。
但是Promise
是不同的。
如果您想为用户提供一些您现在没有的东西,但您认为很快就能拥有它,该怎么办?
这意味着您承诺用户现在没有的东西。
因此,您希望让用户等待,直到您拥有将其提供给用户的内容。那就是当你p.future
并生成一个未来,以便用户可以等待未来的结果。
如果您获得了承诺给用户的结果,那么当发生不良事件时(即通过执行success
),您可以将未来设为failure
或p.complete
,从而为用户提供帮助
即使
onComplete
返回类型更改为Future[T]
。Future
Promise
无法表达或服务于Future.apply
。
也可以使用byte[] ref = {0x71, 0, 0x7e, 0, 5}; // Ref #5
创建未来。在这种情况下,一旦未来的计算完成,未来创建的将完成。
Future用于订阅耗时计算的结果,而Promise可以是发布和订阅模型。