上有什麼在從core.async的Clojure的版本clojurescript提供一定的差異。
因爲在JVM的Clojure有真正的線程,它可以使雙方的併發模式與真正的線程,並與去塊:
真實線程使用宏thread
圍住core.async魔術 及其併發宏和函數以兩個爆炸聲結束,如 <!!
,>!!
,alt!!
和alts!!
。
控制線程 (假線程)的反演使用go
宏以包圍core.async魔術 並使用該功能,並在最後一個的一聲,像<!
,>!
, alt!
和alts!
。
在clojurescript(在JS運行)有沒有真正的線程,所以只有IOC(控制反轉)線程可用,這意味着你必須使用並行結構的第二個變體。
你的例子是這樣的:
(ns shopping-2.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :as async :refer [put! chan <! >! close!]]))
(go
(let [c (chan)]
(>! c "hello")
(.write js/document (<! c))
(close! c)))
反正就是例子有一個併發問題,因爲<! >!
功能是阻止和你投入一個瓚在同一常規,在常規將阻止(>! c "hello")
指令,它永遠不會讀取,肯定會讓你的程序捱餓。
你可以使用put!
FN這使不阻塞,或者在不同的程序我認爲這說明了什麼更好,你打算做efectively運行這些說明解決這個問題。
(ns shopping-2.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :as async :refer [put! chan <! >! close!]]))
;; put! version
(go
(let [c (chan)]
(put! c "hello")
(.write js/document (<! c))
(close! c)))
;; Concurrent version
;; 2 *threads* concurrently running. One is the putter and the other is the
;; reader
(let [c (chan)]
(go
(.write js/document (<! c))
(close! c))
(go
(>! c "hello")))
在併發線程版本,你會看到,即使在運行首先是閱讀代碼,它實際上是另一種例行這樣以後運行代碼(>!
)有效運行,疏通第一個例程。
您可以將go
宏想象爲產生一個新的線程,該線程將最終開始併發執行,並將控制權立即返回到下一代碼指令。
我建議您閱讀code walk-through忽略Clojure的特定部位(>!! <!!
等)和一些swannodette's tutorials這是偉大的(如Clojurescript 101和通信順序進程)
謝謝你這麼多的詳細解釋,一個簡單的「 Clojure腳本不包含阻塞宏「本來就夠了,但這太棒了! 我實際上已經運行了Clojurescript 101教程,並且我正在執行這個演練,這是我被卡住的原因(第30行介紹了阻塞宏,這正是我試圖弄清楚的!) – Samuel
不客氣。我試圖解釋清楚,因爲我從不久前就開始涉足core.async,開始時很難做好準備。 從clojure和clojurescript版本的差異應該在core.async回購的地方... – Joaquin