【问题标题】:Deliver failure (Exception) to a promise将失败(异常)交付给承诺
【发布时间】:2015-03-15 10:30:56
【问题描述】:

我怎样才能让这个承诺的deref 抛出一个异常,就像如果未来的主体抛出一个未来可能会导致一个异常一样?

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

我目前正在考虑通过向 Promise 提供 fn 来执行此操作,但我怀疑有一种更惯用的方式来执行此操作。

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

【问题讨论】:

  • 到目前为止,我决定遵循 erlang 的标记元组方法,并以 [:ok value][:error exception] 的形式将内容交付给承诺。

标签: clojure


【解决方案1】:

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

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

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

deferred 对象可以通过success!error! 函数来实现。前者的行为类似于deliver。后者让您可以通过异常履行承诺,如果 deferred 是 deref'd 则会抛出该异常,但也可以被 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)

【讨论】:

    猜你喜欢
    • 2019-05-27
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 2013-06-28
    相关资源
    最近更新 更多