2017-08-31 62 views
3

我想弄清楚我的REPL中的core.async,並完全混淆了我的用法(go-loop ... )無法成爲異步/>目的的「go block」!爲什麼「斷言失敗:>!不用於(去...)塊」

我去環是像...

(async/go-loop [page (range 3)] 
    (if (empty? page) 
    (async/close! ch) 
    (dorun (map (fn [row] 
        (println row) 
        (async/>! ch row)) page))) 
    (recur (range (dec (count page))))) 

但REPL是全部打亂...

=> 
#object[clojure.core.async.impl.channels.ManyToManyChannel 
     0x23465937 
     "[email protected]"] 
0 
Exception in thread "async-dispatch-12" java.lang.AssertionError: Assert failed: >! used not in (go ...) block 
nil 
... 

爲什麼不是(go-loop ...)足夠的(async/>! row)通話範圍?

我是否應該在這裏使用循環?

+0

[Clojurescript的可能的複製 - 未捕獲錯誤:<!使用不在(去...)塊](https://stackoverflow.com/questions/32037795/clojurescript-uncaught-error-used-not-in-go-block) – OlegTheCat

+0

@OlegTheCat答案可能是相同的,但它不完全相同的問題。就像2 + 5 = 7和8 - 1 = 7並不是同一個問題,即使答案是一樣的。換句話說,如果一個人非常熟悉core.async,這可能看起來像是同一個問題,但是對於一個新的......說google搜尋該異常消息,在尋找這個異常消息時,你不會得到這個Clojurescript問題。 –

回答

7

>!和其他停車場呼叫不能用在嵌套在go裏面的功能裏面。

go將您給它的代碼轉換成狀態機並尋找停車電話。但它並不是看起來嵌套函數的內部。

Clojure.Asyncs Github best practice page

Unsupported constructs and other limitations in go blocks

The go macro stops translating at function creation boundaries. This means the following code will fail to compile, or may just throw a runtime error stating that <! was used outside of a go block:

(go (let [my-fn (fn [] (<! c))] 
    (my-fn))) 

This is one thing to remember since many Clojure constructs create functions inside macros. The following are examples of code that will not work as one would expect:

(go (map <! some-chan)) 
(go (for [x xs] 
     (<! x))) 
+0

so ...'''(do-seq ...'''而不是'''(dorun(地圖...)'''試圖讓我離開我的嵌套函數異常嗎?你可能已經猜到了。 ..我有點新到core.async。 –

+0

@BobKuhar閱讀更新內容。找到官方消息來源。請注意,很多宏都會產生函數,所以也可能不會爲你節省時間。 – Carcigenicate

+1

是的......'''( doseq [row page] ...'''克服了嵌套函數的作用,並且工作得很好謝謝 –