2013-05-02 72 views
4

有没有办法在未来设置手表,以便它在完成时触发回调?当clojure未来完成时,有没有办法通知?

这样的事情?

> (def a (future (Thread/sleep 1000) "Hello World!") 
> (when-done a (println @a)) 

...waits for 1sec... 
;; => "Hello World" 
+0

(的println @a))本身已经块等待运行的println之前完成。你还想要什么? – Chouser 2013-05-03 01:16:41

+0

另外,你可能真正想要的是'NotificationService' – noahlz 2013-05-05 14:36:57

回答

9

您可以启动另一个监视未来,然后运行该功能的任务。在这种情况下,我只会使用另一个未来。这很好地包装成一个时,完成功能:

user=> (defn when-done [future-to-watch function-to-call] 
      (future (function-to-call @future-to-watch))) 
user=> (def meaning-of-the-universe 
     (let [f (future (Thread/sleep 10000) 42)] 
      (when-done f #(println "future available and the answer is:" %)) 
      f)) 
#'user/meaning-of-the-universe 

... waiting ... 

user=> future available and the answer is: 42 
user=> @meaning-of-the-universe 
42 
2

对于非常简单案件: 如果你不想阻止和不关心结果只需在未来的定义中添加回调即可。

(future (a-taking-time-computation) (the-callback)) 

如果你关心结果使用补偿与回调

(future (the-callback (a-taking-time-computation))) 

(future (-> input a-taking-time-computation callback)) 

从语义上讲相当于Java中的代码如下:

final MyCallBack callbackObj = new MyCallBack(); 
new Thread() { 
    public void run() { 
     a-taking-time-computation(); 
     callbackObj.call(); 
    } 
}.start() 

对于复杂的情况你可能会想看看:

https://github.com/ztellman/manifold

https://github.com/clojure/core.async