2014-01-28 10 views
11

我必須在這裏丟失一些非常明顯的東西,但我試圖設置一個非常基本的程序,將一個項目放到一個通道上,然後阻止,直到我可以再次取下它。整個節目低於:似乎無法要求> !!或<!在Clojurescript?

(ns shopping-2.core 
    (:require [cljs.core.async :as async :refer [>!! <!! put! chan <! close! <!!]])) 

(let [c (chan)] 
    (>!! c "hello") 
    (.write js/document (<!! c)) 
    (close! c)) 

的JavaScript錯誤,我得到的是:

Uncaught TypeError: Cannot call method 'call' of undefined 

我時,我忘了之前的錯誤:是指在CHAN(如果我只是打開通道,然後關閉它再次程序運行良好)

但是,此代碼似乎嗆,當我想要使用<!!>!!宏。

回答

29

上有什麼在從core.async的Clojure的版本clojurescript提供一定的差異。

因爲在JVM的Clojure有真正的線程,它可以使雙方的併發模式與真正的線程,並與去塊:

  1. 真實線程使用宏thread圍住core.async魔術 及其併發宏和函數以兩個爆炸聲結束,如 <!!,>!!,alt!!alts!!

  2. 控制線程 (假線程)的反演使用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和通信順序進程)

+0

謝謝你這麼多的詳細解釋,一個簡單的「 Clojure腳本不包含阻塞宏「本來就夠了,但這太棒了! 我實際上已經運行了Clojurescript 101教程,並且我正在執行這個演練,這是我被卡住的原因(第30行介紹了阻塞宏,這正是我試圖弄清楚的!) – Samuel

+1

不客氣。我試圖解釋清楚,因爲我從不久前就開始涉足core.async,開始時很難做好準備。 從clojure和clojurescript版本的差異應該在core.async回購的地方... – Joaquin