未来对象 (futures) 和承诺对象 (promises) 都会在计算其值之前阻塞,所以它们之间有什么区别呢?
未来对象 (futures) 和承诺对象 (promises) 都会在计算其值之前阻塞,所以它们之间有什么区别呢?
以Clojure的术语回答,以下是来自Sean Devlin的视频演示的一些示例:
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
请注意,在 Promise 中,你明确地传递了稍后计算中选择的值(在本例中为 :fred
)。另一方面,Future 是在创建它的同一位置被使用。some-expr
可能会在幕后启动并同时计算,但如果到访问时它仍未评估,则线程将一直阻塞,直到它可用。deref
您的 Promise 的项都将阻塞,直到您完成。一旦您完成并 deliver
承诺,承诺将不再阻塞。deref
您的 Future。如果计算已经完成,则会获取其结果。如果它尚未完成,则会阻塞,直到完成。(假设如果它尚未开始,则 deref
它意味着它开始执行,但这也不是保证。)
虽然你可以将 future 中的表达式设计得和创建 promise 后跟随的代码一样复杂,但这不太可取。这意味着 futures 更适合快速、可以在后台处理的计算,而 promises 更适合于庞大而复杂的执行路径。此外,就可用的计算而言,promises 似乎更灵活,更偏向于 promise 创建者进行工作,而另一个线程则收获成果。而 futures 更偏向于自动启动一个线程(没有繁琐和容易出错的开销)并继续进行其他事情,直到您 - 发起线程 - 需要结果。future
调用的主体可以包括N个sexpr。 - deprecatedFuture和Promise是从生产者向消费者传递异步计算结果的机制。
对于Future,计算在创建Future时就已经定义好,并且异步执行会尽快开始。它还“知道”如何生成异步计算。
对于Promise,计算、启动时间和[可能的] 异步调用与传递机制解耦。当计算结果可用时,生产者必须显式调用deliver
,这也意味着生产者控制结果何时变为可用。
对于Promises,Clojure 在使用相同对象(调用promise
返回的对象)来生产(deliver
)和消费(deref
)计算结果方面存在设计错误。这两个能力是非常不同的,应该分别处理。
promise
耦合是否方便。'恶意'消费者很少见;您可以在承诺之上构建自己的抽象,没有任何限制。 - deprecated(defn undeliverable-promise
[]
(let [p (promise)]
(reify
clojure.lang.IDeref
(deref [_] (deref p))
clojure.lang.IBlockingDeref
(deref [_ ms val] (deref p ms val))
clojure.lang.IPending
(isRealized [_] (.isRealized p))
clojure.lang.IFn
(invoke [_ _] nil))))
- tapichudelay
、future
和promise
之间的区别。Promise
),它们将任务生命周期中的几个(或全部)阶段耦合在一起。例如,在JS中,如果不提供计算其值的函数(任务)或立即使用常量值resolve
它,就无法构建Promise
对象。delay:
任务定义future:
任务执行promise:
任务结果const promise = new Promise((resolve) => resolve(6))
让我们来分解一下:
resolve(6)
是该任务。Promise
中。请注意,在构造Promise
时,你已经安排好了任务运行的时间(在某个未指定的时间)。你无法说“让我将其传递给系统中的另一个组件,让它决定何时运行此任务”。Promise
对象中,并可以通过then
或await
获得。没有办法创建一个“空”的承诺结果,以便由你系统中的尚未知部分填写; 你必须同时定义任务并安排其执行。promise
,由于已经与任务定义和执行分离,现在可以被用作线程间传输的单元。promise
、future
和delay
都是类似于Promise的对象。它们代表了客户端可以通过使用deref
(或@
)等待的计算结果。客户端重复使用结果,以便不会多次运行计算。future
将在不同的工作线程中启动计算。 deref
将阻塞,直到结果准备就绪。
delay
将在第一个客户端使用deref
或force
时惰性地执行计算。
promise
提供最大灵活性,因为可以使用deliver
以任何自定义方式传递其结果。当future
或delay
都不符合您的用例时,可以使用它。
首先,一个 Promise
是一个 Future
。我认为你想知道 Promise
和 FutureTask
之间的区别。
Future
表示当前未知但将来会知道的值。
FutureTask
表示将在未来某个时刻计算的结果(可能在某个线程池中)。当您尝试访问结果时,如果尚未发生计算,则会阻塞。否则,结果会立即返回。没有其他参与方参与计算结果,因为计算是事先由您指定的。
Promise
表示一个结果,将由 promiser 在未来交付给 promisee。在这种情况下,您是 promisee,而 promiser 是给您 Promise
对象的人。与 FutureTask
类似,如果在 Promise
被实现之前尝试访问结果,则会被阻止,直到 promiser 实现了 Promise
。一旦 Promise
被实现,您总是立即获得相同的值。与 FutureTask
不同,这里涉及另一个参与方,即使承诺的制造者。该另一方负责进行计算并实现 Promise
。
从这个意义上说,FutureTask
是您向自己做出的 Promise
。