2016-12-22 19 views
0

次のコア非同期コードを考慮してください。私が起動し、機能を介して外部から間隔を停止する可能性を探していますcore.asyncの開始と終了間隔

(go-loop [] 
    (<! (timeout 2000)) 
    (prn "tick") 
    (recur)) 

:それは「ダニ」2秒ごとに文字列を出力します。

(def running (atom false)) 

(defn start [] 
    (reset! running true) 
    (go (loop [] 
     (<! (timeout 2000)) 
     (prn "tick") 
     (when @running (recur))))) 

(defn stop [] 
    (reset! running false)) 

はこれが移動するための方法です:

私の心に来ただけの事は、このでしたか?または何か他のことをしますか?

答えて

0

は、ここで私はどうなるのかです:

(require '[clojure.core.async :as a]) 

(defn interval [f msecs] 
    (let [timing (a/chan) 
     kickoff 
     #(a/go 
      (a/<! (a/timeout msecs)) 
      (a/>! timing true))] 
    (a/go-loop [] 
     (when (a/<! timing) 
     (a/go (f)) 
     (kickoff) 
     (recur))) 
    (kickoff) 
    #(a/close! timing))) 

例:

(let [i (interval #(prn "tick") 2000)] 
    (Thread/sleep 7000) 
    (i)) 
;; "tick" 
;; "tick" 
;; "tick" 
;;=> nil 

この方法で、すべてのあなたの状態はローカルであり、むしろグローバルアトムを使用するよりも、ブロックをチャネルを介して処理して行くれます。ループの各繰り返しで行われる作業はほぼ一定であるため、実際のインターバル時間は、渡したmsecsの数にかなり近くなるはずです。への別の呼び出しを保証する場合は、年代順に実行し、あなたの代わりにこのような何かを行うことができます:ここでは

(。この関数の使用法は私の以前のinterval機能と同じである)

(require '[clojure.core.async :as a]) 

(defn interval [f msecs] 
    (let [action (a/chan (a/dropping-buffer 1)) 
     timing (a/chan) 
     kickoff 
     #(a/go 
      (a/<! (a/timeout msecs)) 
      (a/>! timing true))] 
    (a/go-loop [] 
     (when (a/<! action) 
     (f) 
     (recur))) 
    (a/go-loop [] 
     (if (a/<! timing) 
     (do 
      (a/>! action true) 
      (kickoff) 
      (recur)) 
     (a/close! action))) 
    (kickoff) 
    #(a/close! timing))) 

fに対するすべての呼び出しはしています同じループ。私は、fへの呼び出しがmsecsよりも長くかかる場合、今後の呼び出しが遅れていくのを開始するかもしれないので、バッファリングを使用しています。ここで

0

は別の方法で、あなたはあなたが名前空間の状態を定義する必要はありません

(defn start [] 
(let [ctl (chan 0)] 
    (go-loop [] 
    (alt! 
     (timeout 2000) (do 
        (prn "tick") 
        (recur)) 
     ctl (prn "Exit "))) 
    ctl)) 


(let [w (start) ] 
    (Thread/sleep 7000) 
    (>!! w "stop")) 

;;=>  "tick" 
     "tick" 
     "Exit"  

を行くことができます。開始機能は将来chanを停止するように戻っています。

関連する問題