4
我想要計算事件的發生率,例如按鍵事件,並顯示它。我也想在事件發生後纔開始計算費率。另一個要求是,在一定數量的按鍵事件之後,費率計算應該停止。我目前的做法是計算Clojure頻道中的事件發生率
(defn keypress-chan
"Returns a channel that receives keys"
[]
(let [out (chan) handler (fn [e] (put! out (.-key e)))]
(js/document.addEventListener "keypress" handler false)
out))
(defn tick
"Pushes to `out` 1000 ms later"
[out]
(go
(<! (timeout 1000))
(>! out 1)))
(defn get-rate
"Calculates keypress per minute rate"
[ticks pressed]
(quot (* pressed 60) ticks))
(defn complete?
[count]
(>= count 100))
(defn main-loop []
(let [key-chan (keypress-chan) ticker-chan (chan)]
(go-loop [pressed 0 ticks 0]
(let [[value ch] (alts! [key-chan ticker-chan])]
(if (= ch key-chan)
(do
;; Start timer to calculate keypress rate
(if (zero? pressed)
(tick ticker-chan))
;; Do something with `value`, i. e. the key being pressed
(when-not (complete?)
(recur (inc pressed) ticks)))
(let [speed (get-rate ticks pressed)]
(swap! app-state assoc :rate rate)
(tick ticker-chan)
(recur pressed (inc ticks))))))))
所以,這個工作,但在main-loop
代碼似乎醜陋的我。我一直在想有一個「觸發器」,只有當第一個值出現在key-chan
並啓動計時器時纔會觸發。然後另一個觸發器在必要時停止定時器。但我是Clojure的新手,不太清楚如何使用async
,所以我無法創建比上述代碼更好的東西。
這個循環如何改進? 我可以將定時器移動到某個功能並通過key-chan
中的第一個值啓動定時器嗎? 如何在稍後停止計時器?
我會保存時間戳在排序列表中的每個按鍵,然後計算在過去的60秒的移動平均率。首先,我不會擔心丟棄舊的價值觀;只需在當前時間的60秒內提取所有值,然後對其進行計數,這就是您的平均速率/分鐘。 –
@AlanThompson,感謝您的想法!將嘗試它。 – coquin