2014-11-13 41 views
5

這是執行非常簡單工作的代碼的當前版本。它啓動10個例程,每個例程向該通道添加10條消息。另一端是一個真正的循環,讀取通道並每隔500毫秒超時。等待Clojure異步頻道的慣用方式是什麼?

我一直在想有更好的東西。我認爲雖然真正的循環可以替換爲它讀取通道的循環,並且在每次成功讀取之後,它可以重新讀取它。如果發生超時,它會終止執行。

我有兩個問題: - 這是正確的做法嗎? - 如何使用Clojure的慣用

(defn -main [& args] 
    (let [c (async/chan)] 
    (doseq [i (range 10)] 
     (async/go 
     (doseq [j (range 10)] 
      (Thread/sleep (rand-int 1000)) 
      (async/>! c (str i " :: " j))))) 
    (while true 
    (async/<!! 
     (async/go 
     (let [[result source] (async/alts! [c (async/timeout 500)])] 
      (if (= source c) 
      (println "Got a value!" result) 
      (println "Timeout!")))))))) 
+2

我會調用任何使用'線程/睡眠'在core.async代碼**總是**代碼的氣味 - 你沒有理由填滿你的線程池。無法想象任何來自'timeout'的<!'或'

+0

...,是的,我同意從頻道循環/重複閱讀將是慣用的。 –

回答

7

這是一個很常見的方法,所以要回答你的第一個問題,我會說是實現它。有通過core.async提供了一些便利,可以使多一點idomatic(雖然它是真的沒事事情是這樣的):

  • 使用go-loop優先於(go (while true ...))或優先(go (loop ...))
  • 使用alt!(let [[result channel]] (alts! ...))