Clojure期货与承诺有何不同?

Zub*_*air 87 terminology future clojure promise

期货和承诺都会阻止,直到他们计算出它们的价值,那么它们之间有什么区别呢?

JUS*_*ION 53

以Clojure术语回答,以下是Sean Devlin的截屏视频:

(def a-promise (promise))
(deliver a-promise :fred)

(def f (future (some-sexp)))
(deref f)
Run Code Online (Sandbox Code Playgroud)

请注意,在承诺中,您明确提供了在稍后的计算中选择的值(:fred在本例中).另一方面,未来正在被创造的同一个地方消费.在some-expr据推测幕后推出,串联(最终)计算的,但如果它仍然通过的时间不计算被访问线程块,直到它可用.


编辑添加

为了进一步区分承诺和未来,请注意以下事项:

诺言

  1. 你创建了一个promise.该promise对象现在可以传递给任何线程.
  2. 你继续计算.这些可能是非常复杂的计算,涉及副作用,下载数据,用户输入,数据库访问,其他承诺 - 无论您喜欢什么.代码看起来非常类似于任何程序中的主线代码.
  3. 完成后,您可以deliver将结果发送到该承诺对象.
  4. deref在您完成计算之前尝试履行承诺的任何项目都会阻止,直到您完成为止.一旦你完成并且你已经deliver履行了承诺,承诺将不再阻止.

未来

  1. 你创造了自己的未来.你未来的一部分是计算的表达.
  2. 未来可能同时执行也可能不会同时执行.可以从池中为其分配一个线程.它可以等待,什么都不做.从你的角度来看,你无法分辨.
  3. 在某些时候你(或另一个线程)deref是未来.如果计算已经完成,您将获得结果.如果尚未完成,则阻止直至完成.(据推测,如果还没有开始,deref那就意味着它开始执行,但这也不能得到保证.)

虽然您可以在将来使表达式像创建承诺之后的代码那样复杂,但是令人怀疑是否可取.这意味着期货更适合快速,可进行背景的计算,而承诺更适合于大型,复杂的执行路径.在可用的计算方面,承诺似乎更加灵活,并且面向承诺创造者完成工作,另一个线索收获丰收.期货更倾向于自动启动一个线程(没有丑陋和容易出错的开销)并继续其他事情,直到你 - 原始线程 - 需要结果.

  • 承诺允许我看起来更灵活.我创造了一个承诺.我将该承诺传递给另一个线程.然后,我可以进行许多复杂的计算,包括等待I/O,从Internet下载数据,等待用户输入等等.完成后,我将使用结果值传递promise.未来涵盖一个S表达式.我想,它可能是一个非常非常复杂的S表达式,但它会有点......僵硬.此外,未来会在线程(或池)中自动执行其工作.在承诺中做同样的事情意味着更多的工作. (2认同)
  • 仅仅为了记录,"未来"呼叫的主体可以包括N个性别. (2认同)

Dim*_*gog 23

Future和Promise都是将生产者与消费者之间的异步计算结果进行通信的机制.

Future的情况下,计算在Future创建时定义,异步执行"ASAP"开始.它还"知道"如何产生异步计算.

在的情况下,承诺计算,它的开始时间和[可能] 异步调用从输送机构分离.当计算结果可用时,Producer必须deliver显式调用,这也意味着Producer控制何时结果可用.

对于Promises Clojure通过使用相同的对象(promise调用结果)来产生设计错误,以产生(deliver)和消耗(deref)计算结果.这是两个非常不同的能力,应该这样对待.

  • 它不是关于安全性的,而是基于能力的编程经常被描述为与安全性有关.在这里,所有关于代码的正确性.经常使用的术语是"通过构造正确",问题是"你能构建一个不正确的程序"吗?不是故意的,而是偶然的.使用单个Promise对象,您可以使用两个单独的对象. (8认同)