2013-05-02 74 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