为什么我们需要 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
但是,我不明白为什么我们需要同时拥有 Future
和 Promise
我想 Promise
是必需的,因为 Future.onComplete
签名
因为 Future.onComplete
return 类型是 Unit
,Future
可能有例外,不能链接
我假设引入 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
获得结果,您可以使用 map
、flatMap
、recover
和 recoverWith
.[=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
并生成一个未来,以便用户可以使用未来等待结果。
一旦你得到了你承诺给用户的结果,当坏事发生时,你通过让未来成为 success
或 failure
来给用户(即通过做 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(())
据我所知,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
return 类型是 Unit
,Future
可能有例外,不能链接
我假设引入 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
获得结果,您可以使用 map
、flatMap
、recover
和 recoverWith
.[=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
并生成一个未来,以便用户可以使用未来等待结果。
一旦你得到了你承诺给用户的结果,当坏事发生时,你通过让未来成为 success
或 failure
来给用户(即通过做 p.complete
).
Even if
onComplete
return type is changed toFuture[T]
.Future
cannot act like or serve purpose ofPromise
.
使用 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 needPromise
, IfonComplete
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(())