2014-01-28 11 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