在clojure中短路期货

Dax*_*ohl 8 asynchronous future clojure promise

我有两个期货可以解决布尔.我基本上想做点什么

(if (or @future1 @future2) 
  ...)
Run Code Online (Sandbox Code Playgroud)

但是,通过优化,无论哪一个完成,如果它是真的,那么我不等待剩余的未来完成; 去吧.当然,如果值为false,则等待剩余的未来完成.有这么简单的方法吗?

Ale*_*art 4

一般情况下,你可以给两个送货员同样的承诺。例如:

(defn foo []
  (let [p (promise)]
    (future
      (Thread/sleep (rand-int 1000))
      (deliver p :a))
    (future 
      (Thread/sleep (rand-int 1000))
      (deliver p :b))
    @p))
Run Code Online (Sandbox Code Playgroud)

调用(foo)将随机产生:a或:b一旦第一次deliver发生就产生;另一个deliver将是空操作。

对于您的具体情况,您需要返回两个布尔值。我唯一能想到的(而且有点混乱)是使用交付者之间共享的第三个承诺:

(defn foo []
  (let [a (promise)
        b (promise)
        link (promise)]
    (future
      (Thread/sleep (rand-int 5000))
      (let [res (rand-nth [true false])]
        (deliver link res)
        (deliver a res)))
    (future
      (Thread/sleep (rand-int 5000))
      (let [res (rand-nth [true false])]
        (deliver link res)
        (deliver b res)))
    {:or (or @link @a @b)  
     :a? (realized? a) 
     :b? (realized? b)
     :link @link
     :a @a 
     :b @b}))
Run Code Online (Sandbox Code Playgroud)
  • 如果先a交付,则立即完成。trueor
  • 如果先a传递,则立即返回,然后阻塞。false@a@b
  • 如果先b交付,则立即完成。trueor
  • 如果先a交付false,则会阻塞@a。

重复调用(foo),您应该会看到预期的结果,具体来说,当:oris 时true,然后有时:a?或:b?will be false,但两者都将始终是trueif :oris false。