Is there a way to be notified when a clojure future finishes?

前端 未结 5 1465
鱼传尺愫
鱼传尺愫 2021-02-04 14:56

Is there a way to set a watch on a future so that it triggers a callback when it is done?

something like this?

> (def a (future (Thread/sleep 1000) \"         


        
5条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-04 15:26

    An extension to the accepted answer

    please note the following caveat:

    with the above when-done implementation the callback will not be invoked if the future is cancelled. That is

    (do
      (def f0 (future (Thread/sleep 1000)))
      (when-done f0 (fn [e] (println "THEN=>" e)))
      (Thread/sleep 500)
      (future-cancel f0))
    

    will not print because the deref call on the cancelled future will raise an exception.

    If you need callbacks to happen i suggest:

    (defn then
      "Run a future waiting on another, and invoke
      the callback with the exit value if the future completes,
      or invoke the callback with no args if the future is cancelled"
      [fut cb]
      (future
        (try
          (cb @fut)
          (catch java.util.concurrent.CancellationException e
            (cb)))))
    
    

    So now this will print:

      (do
        (def f0 (future (Thread/sleep 1000)))
        (then f0 (fn
                   ([] (println "CANCELLED"))
                   ([e] (println "THEN=>" e))))
        (Thread/sleep 500)
        (future-cancel f0))
    
    

提交回复
热议问题