向承诺提供失败(例外)

时间:2015-03-15 10:30:57

标签: clojure

如何让这个承诺的deref抛出异常,就像未来的身体抛出异常会导致异常一样?

(let [p (promise)]
  (something-that-could-deliver-an-error p)
  @p) ; should explode with the delivered Exception

我目前正在考虑通过提供fn承诺来做到这一点,但我怀疑这是一种更惯用的做法。

背景:我同时经营多个期货。如果其中任何一个错误,我想立即取消所有其他期货并输出错误。也许有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

Clojure的诺言没有“成功”和“失败”的单独概念,而是仅区分诺言是否已实现。换句话说,没有办法让Clojure核心承诺在您尊重它时抛出自定义异常。

如果可以使用标准库,则可以尝试使用Manifold中的deferred对象:

http://aleph.io/manifold/deferreds.html

deferred对象可以通过success!error!函数来实现。前者的行为类似于deliver。后者使您可以兑现承诺,但有一个例外,如果推迟了deref,则抛出该例外,但也可以被Manifold的其他控制流功能“捕获”。

user=> (require '[manifold.deferred :as d])
nil
user=> (def my-deferred-value (d/deferred))
#'user/my-deferred-value
user=> (d/error! my-deferred-value (ex-info "Error!" {:failed true}))
true
user=> @my-deferred-value
ExceptionInfo Error!  clojure.core/ex-info (core.clj:4617)